Il mio caso d'uso sta scrivendo numeri in un documento JSON in cui la minimizzazione delle dimensioni è più importante della precisione di numeri molto piccoli/grandi. I numeri rappresentano comunemente unità comuni come millisecondi o metri, che tendono a cadere nell'intervallo [0,001,1000].Densità di informazione numerica massima con printf
In sostanza, mi piacerebbe impostare una lunghezza massima del carattere. Ad esempio, se il limite fosse cinque caratteri, quindi:
casofrom to
1234567 123e4
12345.6 12346
1234.56 1235
123.456 123.5
12.3456 12.35
1.23456 1.235
1.23450 1.235
1.23400 1.234
1.23000 1.23
1.20000 1.2
1.00000 1
0.11111 0.111
0.01111 0.011
0.00111 0.001
0.00011 11e-4
0.00001 1e-5
0.11111 0.111
0.01111 0.011
0.00111 0.001
0.00011 11e-4
0.00001 1e-5
Questo test sembra trasmettere la maggior parte delle informazioni all'interno di un vincolo di lunghezza.
Fallisce con i numeri elevati a potenze esterne all'intervallo [-99.999] e tale intervallo varia in base alla restrizione imposta. Forse il caso di fallimento qui è solo scrivere una stringa più lunga in questi rari casi.
Questo è l'ideale, anche se potrei vivere senza implementarlo io stesso se un'altra soluzione è relativamente vicina, forse troncando invece di arrotondare e non sfruttando la notazione scientifica/esponenziata.
EDIT ecco cosa printf
con %.3f
, %.3g
, %.4g
prodotti per confronto (code here):
printf("%.3f");
match 0 - 1.23457e+06 -> 1234567.000 expected 12e5
match 0 - 12345.6 -> 12345.600 expected 12346
match 0 - 1234.56 -> 1234.560 expected 1235
match 0 - 123.456 -> 123.456 expected 123.5
match 0 - 12.3456 -> 12.346 expected 12.35
match 1 - 1.23456 -> 1.235
match 0 - 1.2345 -> 1.234 expected 1.235
match 1 - 1.234 -> 1.234
match 0 - 1.23 -> 1.230 expected 1.23
match 0 - 1.2 -> 1.200 expected 1.2
match 0 - 1 -> 1.000 expected 1
match 1 - 0.11111 -> 0.111
match 1 - 0.01111 -> 0.011
match 1 - 0.00111 -> 0.001
match 0 - 0.00011 -> 0.000 expected 11e-4
match 0 - 1e-05 -> 0.000 expected 1e-5
match 1 - 0.11111 -> 0.111
match 1 - 0.01111 -> 0.011
match 1 - 0.00111 -> 0.001
match 0 - 0.00011 -> 0.000 expected 11e-4
match 0 - 1e-05 -> 0.000 expected 1e-5
printf("%.3g");
match 0 - 1.23457e+06 -> 1.23e+06 expected 12e5
match 0 - 12345.6 -> 1.23e+04 expected 12346
match 0 - 1234.56 -> 1.23e+03 expected 1235
match 0 - 123.456 -> 123 expected 123.5
match 0 - 12.3456 -> 12.3 expected 12.35
match 0 - 1.23456 -> 1.23 expected 1.235
match 0 - 1.2345 -> 1.23 expected 1.235
match 0 - 1.234 -> 1.23 expected 1.234
match 1 - 1.23 -> 1.23
match 1 - 1.2 -> 1.2
match 1 - 1 -> 1
match 1 - 0.11111 -> 0.111
match 0 - 0.01111 -> 0.0111 expected 0.011
match 0 - 0.00111 -> 0.00111 expected 0.001
match 0 - 0.00011 -> 0.00011 expected 11e-4
match 0 - 1e-05 -> 1e-05 expected 1e-5
match 1 - 0.11111 -> 0.111
match 0 - 0.01111 -> 0.0111 expected 0.011
match 0 - 0.00111 -> 0.00111 expected 0.001
match 0 - 0.00011 -> 0.00011 expected 11e-4
match 0 - 1e-05 -> 1e-05 expected 1e-5
printf("%.4g");
match 0 -> 1.23457e+06 -> 1.235e+06 expected 12e5
match 0 -> 12345.6 -> 1.235e+04 expected 12346
match 1 -> 1234.56 -> 1235
match 1 -> 123.456 -> 123.5
match 1 -> 12.3456 -> 12.35
match 1 -> 1.23456 -> 1.235
match 0 -> 1.2345 -> 1.234 expected 1.235
match 1 -> 1.234 -> 1.234
match 1 -> 1.23 -> 1.23
match 1 -> 1.2 -> 1.2
match 1 -> 1 -> 1
match 0 -> 0.11111 -> 0.1111 expected 0.111
match 0 -> 0.01111 -> 0.01111 expected 0.011
match 0 -> 0.00111 -> 0.00111 expected 0.001
match 0 -> 0.00011 -> 0.00011 expected 11e-4
match 0 -> 1e-05 -> 1e-05 expected 1e-5
match 0 -> 0.11111 -> 0.1111 expected 0.111
match 0 -> 0.01111 -> 0.01111 expected 0.011
match 0 -> 0.00111 -> 0.00111 expected 0.001
match 0 -> 0.00011 -> 0.00011 expected 11e-4
match 0 -> 1e-05 -> 1e-05 expected 1e-5
Sicuramente il primo esempio è meglio espresso come '123e4'? – NPE
@NPE hai ragione - ha emendato e incluso alcune informazioni su potenziali casi di errore su numeri molto piccoli/grandi. –
'printf' con' "% .4g" 'abbastanza vicino? (In alcuni casi è troppo lungo.) – mafso