W moim przypadku użycia zapisuję liczby w dokumencie JSON, w którym minimalizacja rozmiaru jest ważniejsza niż precyzja bardzo małych/dużych liczb. Liczby zwykle reprezentują typowe jednostki, takie jak milisekundy lub metry, które zwykle mieszczą się w zakresie [0.001,1000].Maksymalna liczbowa gęstość informacji z printf
Zasadniczo chciałbym ustawić maksymalną długość znaku. Na przykład, jeśli limit zawiera pięć znaków, wówczas:
from 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
Ten przypadek testowy wydaje się zawierać najwięcej informacji w ramach ograniczenia długości.
Nie udaje się z liczbami podniesionymi do uprawnień spoza zakresu [-99,999], a zakres ten będzie różny w zależności od nałożonego ograniczenia. Być może przypadek awarii tutaj jest po prostu napisać dłuższy ciąg w tych rzadkich przypadkach.
Jest to ideał, chociaż mógłbym żyć bez jego implementacji, jeśli inne rozwiązanie jest względnie bliskie, być może obcięcie zamiast zaokrąglania, a nie wykorzystanie zapisu naukowego/potęgowanego.
EDIT oto co printf
z %.3f
, %.3g
, %.4g
produktów przez porównanie (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
Z pewnością pierwszy przykład jest lepiej wyrażony jako "123e4"? – NPE
@NPE masz rację - poprawiono i dodano kilka informacji o potencjalnych przypadkach niepowodzenia na bardzo małych/dużych numerach. –
Czy 'printf' z' "% .4g" 'wystarczająco blisko? (W niektórych przypadkach jest zbyt długi.) – mafso