Shell Rounding

$ printf "%0.2f\n" 41.495
41.49
$ printf "%0.2f\n" 41.485
41.49
$ printf "%0.2f\n" 41.475
41.47
$ printf "%0.2f\n" 41.465
41.47
$ printf "%0.2f\n" 41.455
41.46
$ printf "%0.2f\n" 41.445
41.44
$ printf "%0.2f\n" 41.435
41.44
$ printf "%0.2f\n" 41.425
41.42
$ printf "%0.2f\n" 41.415
41.42
$ printf "%0.2f\n" 41.405
41.40

Why are numbers with an uneven number, since the second decimal code is not correctly rounded and even one? Also, what's wrong with .445 that it never rounds?

+5
source share
4 answers

It deals with floating point, but not double precision.

When you write

printf "%0.2f\n" 41.495

on your system, the printffirst rounds 41.495to the nearest 80-bit floating-point number x87 [1]. How it works? First write 41.495 in binary format:

b101001.0111 11101011100001010001 11101011100001010001 11101011100001010001 ...

(divided groups are repeated ad infinitum). Now we round this number to have 64 binary digits:

b101001.0111111010111000010100011110101110000101000111101011100001

This is the number that printf actually formatted. Written in decimal, that's for sure:

41.4949999999999999990285548534529880271293222904205322265625

, , 41,495, , printf , 41.49 .

41.485; 64 :

41.48500000000000000055511151231257827021181583404541015625

, 41.485, printf .

printf:

ASCII , , .


  • bash x87 (, ); ( 53 64), .
+7

, IEEE Double precision floating point. , , , . 100% - , , "" , , , . , .

wiki. . , , .

+2

shell printf , , 80- Intels. printf , , /usr/bin/printf.

( IEEE 754) 41,495 41,494998931884765625. , "41.495" , 41.494998931884765625. , 41.49, "499..." .

41.495 - 41.494999999999999999090285548534529880271293222904205322265625. , "41.495" , 41,4949999999999999990902125348534529880271293222904205322265625. , 41.49.

41.485 41.48500000000000000055511151231257827021181583404541015625. 41.49.

41.475 41.474999999999999998612221219218554324470460414886474609375. 41.47.

41.465 41.4650000000000000001387778780781445675529539585113525390625. 41.47.

41.455 41.45500000000000000166533453693773481063544750213623046875. , 41.46.

41.445 41.444999999999999999722444243843710864894092082977294921875. 41.44.

41,435 41,4350000000000000012490009027033011079765856266021728515625. 41.44.

41.425 41.424999999999999999973061106096092771622352302074432373046875. 41.42.

41.415 41.415000000000000000832667268468867405317723751068115234375. 41.42.

The closest value for extended accuracy to 41.405 is 41.4049999999999999988897769753748434595763683319091796875. When rounding is 41.40.

+2
source

You may have bash to show exactly what it does inside: printf "%0.20f\n" 41.495In the trial version and error, the next smallest number that another representation registers is: printf "%0.20f\n" 41.495000000000000001which is actually more accurate than double precision. Actually, this is all the printf command. bash does not actually understand floating point numbers.

0
source

All Articles