Home > Archive > AWK > February 2007 > A printf and rounding question
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
A printf and rounding question
|
|
| Hermann Peifer 2007-01-28, 3:57 am |
| Dear All,
As I know from own experience and from the AWK manual, I have to be
careful with printf's rounding logic:
---snip---
12.2.4 Rounding Numbers
The way printf and sprintf (see Printf) perform rounding often depends
upon the system's C sprintf subroutine. On many machines, sprintf
rounding is “unbiased,” which means it doesn't always round a trailing
`.5' up, contrary to naive expectations.
---snip---
http://www.gnu.org/software/gawk/ma...#Round-Function
My question is now: can someone help me to understand my own printf's
rounding logic, which is not normal=biased=round-5-up, nor
unbiased=round-5-to-even, nor round-5-to-odd (always talking about the
trailing 5 in the fraction). The results are just confusing, at least to
me, see below.
$ printf "%.3f\n" 3.5115
3.511
$ printf "%.3f\n" 3.5125
3.513
$ printf "%.3f\n" 3.5135
3.514
$ printf "%.3f\n" 3.5145
3.514
$ printf "%.3f\n" 3.5155
3.515
$ printf "%.3f\n" 3.5165
3.517
$ printf "%.3f\n" 3.5175
3.518
$ printf "%.3f\n" 3.5185
3.518
$ printf "%.3f\n" 3.5195
3.519
Or is this all some Cygwin hokus-pokus?
$ cat /proc/version
CYGWIN_NT-5.1 1.5.21(0.156/4/2) 2006-07-30 14:21
Or is it perhaps related to the more generic problem that computers with
their binary logic have some (more or less predictable) difficulties
with floating-point numbers from the decimal system?
see e.g. at: http://docs.sun.com/source/806-3568/ncg_goldberg.html
Thanks, Hermann
| |
| Hermann 2007-01-28, 3:57 am |
| On Jan 28, 7:01 am, Hermann Peifer <pei...@gmx.net> wrote:
>
> $ printf "%.3f\n" 3.5115
> 3.511
>
> $ printf "%.3f\n" 3.5125
> 3.513
>
> $ printf "%.3f\n" 3.5135
> 3.514
>
> $ printf "%.3f\n" 3.5145
> 3.514
>
> $ printf "%.3f\n" 3.5155
> 3.515
>
> $ printf "%.3f\n" 3.5165
> 3.517
>
> $ printf "%.3f\n" 3.5175
> 3.518
>
> $ printf "%.3f\n" 3.5185
> 3.518
>
> $ printf "%.3f\n" 3.5195
> 3.519
>
> Or is this all some Cygwin hokus-pokus?
>
> $ cat /proc/version
> CYGWIN_NT-5.1 1.5.21(0.156/4/2) 2006-07-30 14:21
>
>Or is it perhaps related to the more generic problem that computers with
> their binary logic have some (more or less predictable) difficulties
> with floating-point numbers from the decimal system?
> see e.g. at: http://docs.sun.com/source/806-3568/ncg_goldberg.html
Now I am really puzzled:
peifer@zorro:~> printf "%.3f\n" 3.5105
3.511
peifer@zorro:~> printf "%.3f\n" 3.5115
3.512
peifer@zorro:~> printf "%.3f\n" 3.5125
3.513
peifer@zorro:~> printf "%.3f\n" 3.5135
3.514
peifer@zorro:~> printf "%.3f\n" 3.5145
3.515
peifer@zorro:~> printf "%.3f\n" 3.5155
3.516
peifer@zorro:~> printf "%.3f\n" 3.5165
3.516
peifer@zorro:~> printf "%.3f\n" 3.5175
3.517
peifer@zorro:~> printf "%.3f\n" 3.5185
3.518
peifer@zorro:~> printf "%.3f\n" 3.5195
3.519
peifer@zorro:~> cat /proc/version
Linux version 2.6.13-15.7-default (g o@buildhost) (gcc version 4.0.2
20050901 (prerelease) (SUSE Linux)) #1 Tue Nov 29 14:32:29 UTC 2005
peifer@zorro:~>
Any help is welcome. Perhaps you could give it a try with the printf
on your machine
Thanks, Hermann
| |
|
|
On Jan 28, 9:37 am, "Hermann" <pei...@gmx.net> wrote:
> On Jan 28, 7:01 am, Hermann Peifer <pei...@gmx.net> wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> peifer@zorro:~> printf "%.3f\n" 3.5105
> 3.511
> peifer@zorro:~> printf "%.3f\n" 3.5115
> 3.512
> peifer@zorro:~> printf "%.3f\n" 3.5125
> 3.513
> peifer@zorro:~> printf "%.3f\n" 3.5135
> 3.514
> peifer@zorro:~> printf "%.3f\n" 3.5145
> 3.515
> peifer@zorro:~> printf "%.3f\n" 3.5155
> 3.516
> peifer@zorro:~> printf "%.3f\n" 3.5165
> 3.516
> peifer@zorro:~> printf "%.3f\n" 3.5175
> 3.517
> peifer@zorro:~> printf "%.3f\n" 3.5185
> 3.518
> peifer@zorro:~> printf "%.3f\n" 3.5195
> 3.519
>
> peifer@zorro:~> cat /proc/version
> Linux version 2.6.13-15.7-default (g o@buildhost) (gcc version 4.0.2
> 20050901 (prerelease) (SUSE Linux)) #1 Tue Nov 29 14:32:29 UTC 2005
> peifer@zorro:~>
>
> Any help is welcome. Perhaps you could give it a try with the printf
> on your machine
>
> Thanks, Hermann
It could be due to the internal representation of the floating point
numer sometimes being above or beow what you think. Try printing %.33f
or something.
- Paddy.
| |
| Janis Papanagnou 2007-01-28, 7:57 am |
| Hermann Peifer wrote:
>
> Thanks indeed, although I am getting even more puzzled.
>
> This basically tells me that it is time now to open another thread in
> this group on how to expand the round.awk function from the GAWK manual,
> correct?
>
> One of my thoughts in a previous posting was that some of the issues
> behind the (somewhat) unpredictable results can be avoided when
> splitting the floating point number into the 2 parts, as the fractional
> part would become an integer this way. Is this thought reasonable?
Hmm.., maybe. I am usure whether awk will read and store data that matches
a numerical value as a string or whether it will already convert it to a
FP number thus suffering from the inherent conversion inaccuracies. But at
least you may try that approach.
{ split($0,fp,"[,.]"); print fp[1], fp[2] }
will give you the two parts and using the length and substr function may
solve your problem.
Janis
>
> Hermann
>
> PS
> On this Sunday morning, my 10-year-old son is sitting next to me on
> another PC, playing World of Warcraft. I asked him what he knows about
> rounding, in particular about cases with a trailing 5. "Why? A trailing
> 5 is always rounded up", he said. "Everyone in our 4th grade class knows
> about that."
At that time I also "knew" that. But mind, mathematics is not computer
science.
Mathematics may be hard, but to make things really disgusting you need
a computer. (I read something along that line a couple of years ago.)
| |
| Hermann Peifer 2007-01-28, 6:57 pm |
| Janis Papanagnou wrote:
> Hermann Peifer wrote:
>
> Hmm.., maybe. I am usure whether awk will read and store data that matches
> a numerical value as a string or whether it will already convert it to a
> FP number thus suffering from the inherent conversion inaccuracies. But at
> least you may try that approach.
>
> { split($0,fp,"[,.]"); print fp[1], fp[2] }
>
> will give you the two parts and using the length and substr function may solve...
Thanks for the hint.
> ...your problem.
>
I still have some vague hope that this rounding issue is not only *my*
problem. It should be a known issue (which someone has already solved
years ago by writing the AWK function I am looking for).
As it is only a rounding, but not a burning issue ;-) I will wait
another day or two. Perhaps someone will point me in the right direction.
Hermann
| |
| Carl Lowenstein 2007-01-30, 3:57 am |
| In article <45bc3c3e$0$71749$edfadb0f@dread11.news.tele.dk>,
Hermann Peifer <peifer@gmx.net> wrote:
>Dear All,
>
>As I know from own experience and from the AWK manual, I have to be
>careful with printf's rounding logic:
>
>My question is now: can someone help me to understand my own printf's
>rounding logic, which is not normal=biased=round-5-up, nor
>unbiased=round-5-to-even, nor round-5-to-odd (always talking about the
>trailing 5 in the fraction). The results are just confusing, at least to
>me, see below.
>
>$ printf "%.3f\n" 3.5115
>3.511
>
>$ printf "%.3f\n" 3.5125
>3.513
>
>$ printf "%.3f\n" 3.5135
>3.514
>
>$ printf "%.3f\n" 3.5145
>3.514
>
>
>Or is it perhaps related to the more generic problem that computers with
>their binary logic have some (more or less predictable) difficulties
>with floating-point numbers from the decimal system?
>see e.g. at: http://docs.sun.com/source/806-3568/ncg_goldberg.html
It is precisely related to the fact that an "exact" decimal fraction
can almost never be expressed exactly as a binary floating-point number.
So when you write 3.5135 the computer will express it as either 117893496
* 2^-25 or 117893497 * 2^-25. One of these values is slightly less than
3.5135, the other is slightly greater. Similarly, the round-off value of
0.0005 to be added to this will have some binary approximation which is
not exactly equal to 0.0005. And the sum will be a binary number that
you will then have to find the nearest decimal approximation to.
Kernighan and Plauger:
"Floating point numbers are like piles of sand; every time you move
one you lose a little sand and pick up a little dirt."
carl
--
carl lowenstein marine physical lab u.c. san diego
clowenst@ucsd.edu
| |
| Hermann Peifer 2007-01-30, 6:57 pm |
| Carl Lowenstein wrote:
> In article <45bc3c3e$0$71749$edfadb0f@dread11.news.tele.dk>,
> Hermann Peifer <peifer@gmx.net> wrote:
>
> It is precisely related to the fact that an "exact" decimal fraction
> can almost never be expressed exactly as a binary floating-point number.
> So when you write 3.5135 the computer will express it as either 117893496
> * 2^-25 or 117893497 * 2^-25. One of these values is slightly less than
> 3.5135, the other is slightly greater. Similarly, the round-off value of
> 0.0005 to be added to this will have some binary approximation which is
> not exactly equal to 0.0005. And the sum will be a binary number that
> you will then have to find the nearest decimal approximation to.
>
> Kernighan and Plauger:
> "Floating point numbers are like piles of sand; every time you move
> one you lose a little sand and pick up a little dirt."
>
> carl
Thanks for the explanation and the quote.
In principle, I was aware of the problems with binary floating-point
numbers. I did however believe that this would only affect computer
scientists doing some mega-calculations on their super-computers and not
me with my trivial rounding of small numbers.
Now I know better.
Hermann
| |
| Steffen Schuler 2007-01-31, 9:57 pm |
| Hermann Peifer wrote:
> Dear All,
>
> As I know from own experience and from the AWK manual, I have to be
> careful with printf's rounding logic:
>
> ---snip---
> 12.2.4 Rounding Numbers
> The way printf and sprintf (see Printf) perform rounding often depends
> upon the system's C sprintf subroutine. On many machines, sprintf
> rounding is “unbiased,” which means it doesn't always round a trailing
> `.5' up, contrary to naive expectations.
> ---snip---
>
> http://www.gnu.org/software/gawk/ma...#Round-Function
>
> My question is now: can someone help me to understand my own printf's
> rounding logic, which is not normal=biased=round-5-up, nor
> unbiased=round-5-to-even, nor round-5-to-odd (always talking about the
> trailing 5 in the fraction). The results are just confusing, at least to
> me, see below.
>
> $ printf "%.3f\n" 3.5115
> 3.511
>
> $ printf "%.3f\n" 3.5125
> 3.513
>
> $ printf "%.3f\n" 3.5135
> 3.514
>
> $ printf "%.3f\n" 3.5145
> 3.514
>
> $ printf "%.3f\n" 3.5155
> 3.515
>
> $ printf "%.3f\n" 3.5165
> 3.517
>
> $ printf "%.3f\n" 3.5175
> 3.518
>
> $ printf "%.3f\n" 3.5185
> 3.518
>
> $ printf "%.3f\n" 3.5195
> 3.519
>
> Or is this all some Cygwin hokus-pokus?
>
> $ cat /proc/version
> CYGWIN_NT-5.1 1.5.21(0.156/4/2) 2006-07-30 14:21
>
> Or is it perhaps related to the more generic problem that computers with
> their binary logic have some (more or less predictable) difficulties
> with floating-point numbers from the decimal system?
> see e.g. at: http://docs.sun.com/source/806-3568/ncg_goldberg.html
>
> Thanks, Hermann
A good document to the floating point arithmetic:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
Enjoy,
Steffen
| |
| Hermann 2007-02-02, 3:56 am |
| On Feb 1, 1:23 am, Steffen Schuler <schuler.steffenDELETE_T...@gmx.de>
wrote:
> Hermann Peifer wrote:
>
>
> A good document to the floating point arithmetic:
>
> http://docs.sun.com/source/806-3568/ncg_goldberg.html <---
>
> Enjoy,
>
> Steffen
I assume you did not read the last lines of my article before replying
-- or do I miss the joke?
Puzzled, Hermann
|
|
|
|
|