Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get different output on linux and OS/X

I was trying a very simple printf test:

printf "%.16f\n" 5.10

On linux I got this output: 5.100000000000000000 which is expected.

But the very same test on OS/X produces this: 5.0999999999999996

Why does printf produce different output?

EDIT: This is not C code, printf is also a command-line utility, handy for scripts and tests.

The equivalent C program below produces 5.100000000000000000:

#include <stdio.h>

int main() {
    printf("%.16f\n", 5.10);
    return 0;
}

EDIT 2: The plot thickens... to make this more interesting for linux users, if I run this command as nobody, I get the same behavior as on OS/X:

chqrlie$ printf "%.18f\n" 5.10
5.100000000000000000
chqrlie$ su nobody -c 'printf "%.18f\n" 5.10'
5.099999999999999645
like image 282
chqrlie Avatar asked Apr 12 '19 07:04

chqrlie


People also ask

Can I run Linux terminal on mac?

If you use MacOS® X, you don't need to install a third-party client like PuTTY to connect to your cloud server by using Secure Shell (SSH). Terminal is a terminal emulation program included with MacOS X that you can use to run SSH.

Does BASH work on mac?

Historically, the default shell for macOS was bash. But with the introduction of macOS Catalina Apple changed the default to zsh (zshell).


1 Answers

Both the GNU implementation and the MacOS (FreeBSD) implementation of printf are different programs. Both aim to be compatible with the POSIX standard.

POSIX leaves the representation of floating point numbers open to the implementation of printf. Their argumentation is that all calculation in shell is integer anyway.

The floating-point formatting conversion specifications of printf() are not required because all arithmetic in the shell is integer arithmetic. The awk utility performs floating-point calculations and provides its own printf function. The bc utility can perform arbitrary-precision floating-point arithmetic, but does not provide extensive formatting capabilities. (This printf utility cannot really be used to format bc output; it does not support arbitrary precision.) Implementations are encouraged to support the floating-point conversions as an extension.

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html


PS:

5.1

is not a floating point number in bash. bash does not support floating numbers.

5.1 is a string, interpreted by printf depending on the locale(!)

theymann@theymann-laptop:~/src/sre/inventory-schema$ LANG=en_US.UTF8 printf "%.16f\n" 5.10
5.1000000000000000
theymann@theymann-laptop:~/src/sre/inventory-schema$ LANG=de_DE.UTF8 printf "%.16f\n" 5.10
bash: printf: 5.10: Ungültige Zahl. # << German: Bad Number
0,0000000000000000

Note: In Germany we use , as the decimal separator.


The difference in the output between a normal user and nobody must the shell which is used. some shells, like busybox come with their own implementation of printf. Btw, I'm extremely surprised that nobody is allowed to execute commands on your system!

like image 171
hek2mgl Avatar answered Nov 07 '22 05:11

hek2mgl