Home > Archive > AWK > December 2004 > Problem with floating point arithmetic
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 |
Problem with floating point arithmetic
|
|
|
| Hi all. Major newbie here. I'm learning awk trying the examples in chapter
4 of Kernighan and Pike's classic text "The Unix Programming Environment"
but I'm experiencing some problems with small float values. In the book
there's an example to calculate totals by name. Using the input file:
Susie 400
John 100
Mary 200
Mary 300
John 100
Susie 100
Mary 100
The program:
{ sum[$1] += $2 }
END { for (name in sum) print name, sum[name] }
calculates the totals:
Mary 600
John 200
Susie 500
The problem arises when I try this with floating point values:
Susie 1,2
John 0,1
Mary 1
Mary 0,4
John 0,33
Susie 0,48
Mary 1,1
The output of the programa now is:
Mary 2,1
John 0
Susie 1,2
If I try dots instead of commas:
Susie 1.2
John 0.1
Mary 1
Mary 0.4
John 0.33
Susie 0.48
Mary 1.1
I get equally wrong results:
Mary 2
John 0
Susie 1
What's wrong? I'm using GAWK (the version that's shipped with Mandrake
10.1)
| |
| Janis Papanagnou 2004-12-07, 3:59 am |
| ELG wrote:
>
> { sum[$1] += $2 }
> END { for (name in sum) print name, sum[name] }
>
> The problem arises when I try this with floating point values:
>
> If I try dots instead of commas:
>
> Susie 1.2
> John 0.1
> Mary 1
> Mary 0.4
> John 0.33
> Susie 0.48
> Mary 1.1
>
> I get equally wrong results:
>
> Mary 2
> John 0
> Susie 1
That's an effect of the configured locale, I suppose.
(I get these values when I use commas instead of dots.)
> What's wrong? I'm using GAWK (the version that's shipped with Mandrake
> 10.1)
Susie 1.2
John 0.1
Mary 1
Mary 0.4
John 0.33
Susie 0.48
Mary 1.1
Mary 2.5
John 0.43
Susie 1.68
Works for me.
% awk --version
GNU Awk 3.1.1
Janis
| |
| Bob Harris 2004-12-07, 3:59 am |
| In article <pan.2004.12.02.23.43.57.731305@nospam.net>,
ELG <ELG@nospam.net> wrote:
> Hi all. Major newbie here. I'm learning awk trying the examples in chapter
> 4 of Kernighan and Pike's classic text "The Unix Programming Environment"
> but I'm experiencing some problems with small float values. In the book
> there's an example to calculate totals by name. Using the input file:
>
> Susie 400
> John 100
> Mary 200
> Mary 300
> John 100
> Susie 100
> Mary 100
>
> The program:
>
> { sum[$1] += $2 }
> END { for (name in sum) print name, sum[name] }
>
> calculates the totals:
>
> Mary 600
> John 200
> Susie 500
>
> The problem arises when I try this with floating point values:
>
> Susie 1,2
> John 0,1
> Mary 1
> Mary 0,4
> John 0,33
> Susie 0,48
> Mary 1,1
>
> The output of the programa now is:
>
> Mary 2,1
> John 0
> Susie 1,2
>
> If I try dots instead of commas:
>
> Susie 1.2
> John 0.1
> Mary 1
> Mary 0.4
> John 0.33
> Susie 0.48
> Mary 1.1
>
> I get equally wrong results:
>
> Mary 2
> John 0
> Susie 1
>
> What's wrong? I'm using GAWK (the version that's shipped with Mandrake
> 10.1)
what is the value of OFMT ? This is the output format specifier for
numeric values
awk 'BEGIN{print OFMT}'
The general default is %.6g
If it anything else, then that might be the problem.
Bob Harris
| |
| William James 2004-12-07, 3:59 am |
| Perhaps the default format for floats is wrong.
Add this to your program:
BEGIN { print OFMT; OFMT="%.6g" }
| |
| Koriolan 2004-12-07, 3:59 am |
| Prawdziwa Blondynka napisał(a):
> Hi,
> I have exactly the same problem, my OFMT is right. Do you have any
> other ideas about what could be wrong?
> I'm working on Solaris...
I have the same problem but my awk bad interpreted :
"0.45" + 1 => 1"
----------------
Jak masz ustawiony polski język to wtedy kropką jest przecinek :-(.
Co prawda nic to nie dało, bo źle interpretował część ułamkową :-(
Ja napisałem sobie króciutką funkcję :
....
function s_tonum ( sliczba, znak,c,u ) {
# Funkcja poprawnie konweryje strind na liczbę rzeczywistą
# np. " 0.23" (ang.) lub " 0,23" (polski jezyk)
#
gsub( / /, "", sliczba);
znak = index( sliczba, ".");
if (znak == 0) index( sliczba, ",");
if (znak == 0) return strtonum( sliczba);
c = strtonum( substr( sliczba, 1, znak -1 ));
u = substr( sliczba, znak + 1);
return ( c + ( u/(10**length(u)) ));
};
.....
number = s_tonum( " 0.456");
.....
Koriolan
| |
|
| Janis Papanagnou wrote:
>
> That's an effect of the configured locale, I suppose.
> (I get these values when I use commas instead of dots.)
>
Thank you for your reply. Can you please post the output of the locale
command in your system so I'm able to properly configure mine?
| |
| Prawdziwa Blondynka 2004-12-07, 3:59 am |
| w_a_x_man@yahoo.com (William James) wrote in message news:<f8860640.0412022225.c11089d@posting.google.com>...
> Perhaps the default format for floats is wrong.
> Add this to your program:
>
> BEGIN { print OFMT; OFMT="%.6g" }
Hi,
I have exactly the same problem, my OFMT is right. Do you have any
other ideas about what could be wrong?
I'm working on Solaris...
Thanks,
Blondie
| |
| Patrick TJ McPhee 2004-12-07, 3:59 am |
| In article <harris-2D29F0.20510004122004@cacnews.cac.cpqcorp.net>,
Bob Harris <harris@zk3.dec.com> wrote:
% Isn't there 2 awk's available on sun? One called awk, and one called
% nawk ???
On the most recent sun machines, there are generally four awks available --
one called awk, another called awk, another called nawk and one called gawk.
% If I recall previous posts to this news group, the default 'awk' version
% is very old and moldy. The 'nawk' version is the more capable version
% of awk shipped by sun.
/usr/bin/awk is the old and moldy version. If you put /usr/xpg4/bin first
in your path, then the default awk is supposed to be posix-compliant (ditto
for the other utilities).
--
Patrick TJ McPhee
North York Canada
ptjm@interlog.com
| |
| William James 2004-12-07, 8:55 am |
| Change
if (znak == 0) index( sliczba, ",");
to
if (znak == 0) znak = index( sliczba, ",")
Even better:
-------------------------------------------
function s_tonum( s )
{
gsub( /,/, ".", s )
return s + 0
}
BEGIN {
number = s_tonum( " 0,456 " ) + 1
print number
}
| |
|
| Janis Papanagnou wrote:
>
> That's an effect of the configured locale, I suppose.
> (I get these values when I use commas instead of dots.)
>
Thank you for your reply. Can you please post the output of the locale
command in your system so I'm able to properly configure mine?
| |
| Prawdziwa Blondynka 2004-12-10, 8:55 pm |
| w_a_x_man@yahoo.com (William James) wrote in message news:<f8860640.0412022225.c11089d@posting.google.com>...
> Perhaps the default format for floats is wrong.
> Add this to your program:
>
> BEGIN { print OFMT; OFMT="%.6g" }
Hi,
I have exactly the same problem, my OFMT is right. Do you have any
other ideas about what could be wrong?
I'm working on Solaris...
Thanks,
Blondie
| |
| Bob Harris 2004-12-11, 3:55 am |
| In article <b1573e9b.0412041308.1447e2fb@posting.google.com>,
blondie21@poczta.onet.pl (Prawdziwa Blondynka) wrote:
> w_a_x_man@yahoo.com (William James) wrote in message
> news:<f8860640.0412022225.c11089d@posting.google.com>...
>
>
> Hi,
> I have exactly the same problem, my OFMT is right. Do you have any
> other ideas about what could be wrong?
> I'm working on Solaris...
>
> Thanks,
> Blondie
Isn't there 2 awk's available on sun? One called awk, and one called
nawk ???
If I recall previous posts to this news group, the default 'awk' version
is very old and moldy. The 'nawk' version is the more capable version
of awk shipped by sun.
But I have never used a Sun system, so I could be relating incorrect
information.
Bob Harris
| |
| William James 2004-12-11, 3:55 pm |
| Change
if (znak == 0) index( sliczba, ",");
to
if (znak == 0) znak = index( sliczba, ",")
Even better:
-------------------------------------------
function s_tonum( s )
{
gsub( /,/, ".", s )
return s + 0
}
BEGIN {
number = s_tonum( " 0,456 " ) + 1
print number
}
|
|
|
|
|