Results 1 to 10 of 13
Hi,
I am puzzled by the output of the following program (compile using
gcc a.c -lm)
#include <stdio.h>
#include <math.h>
int main(void){
printf("log(1000)/log(10)=%f\nfloor(log(1000)/log(10))=%f (correct is 3)\n",
log(1000.0)/log(10.0), floor(log(1000.0)/log(10.0)) );
}
...
- 11-07-2007 #1Just Joined!
- Join Date
- Nov 2007
- Posts
- 2
math's wrong in linux, suse 10.0 pentium4
Hi,
I am puzzled by the output of the following program (compile using
gcc a.c -lm)
#include <stdio.h>
#include <math.h>
int main(void){
printf("log(1000)/log(10)=%f\nfloor(log(1000)/log(10))=%f (correct is 3)\n",
log(1000.0)/log(10.0), floor(log(1000.0)/log(10.0)) );
}
response in my system:
log(1000)/log(10)=3.000000
floor(log(1000)/log(10))=2.000000 (correct is 3)
whereas log(1000)/log(10) is 3.0, the floor function returns 2.0 !!!!!
even if i use typecasting i.e.
(int )(log(1000.0)/log(10.0))
I get the same answer 2.0 - it must be 3.0
can you reproduce this on your system?
am i doing something wrong or is there a bug?
please let me know if you need more information about my system
thanks,
andreas
my system:
> uname -a
Linux 2.6.18.2-34-default #1 SMP Mon Nov 27 11:46:27 UTC 2006 i686 i686 i386 GNU/Linux
> gcc -v
Using built-in specs.
Target: i586-suse-linux
Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.1.2 --enable-ssp --disable-libssp --disable-libgcj --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit --enable-libstdcxx-allocator=new --program-suffix=-4.1 --enable-version-specific-runtime-libs --without-system-libunwind --with-cpu=generic --host=i586-suse-linux
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)
- 11-07-2007 #2
Your program is behaving correctly. It seems counterintuitive, but the problem arises from roundoff error; binary floating point, or floating point in any radix, can't possibly produce irrational numbers exactly. Run this
and you'll getCode:#include <stdio.h> #include <math.h> int main(void){ printf("log(1000) =%25.20f\n", log(1000.0) ); printf("log(10) =%25.20f\n", log(10.0) ); printf("log(1000)/log(10)=%25.20f\n", log(1000.0)/log(10.0) ); return 0; }
Hope this helps.Code:log(1000) = 6.90775527898213681510 log(10) = 2.30258509299404590109 log(1000)/log(10)= 2.99999999999999955591
- 11-07-2007 #3
In maths infinite numbers exist but not in computers, so for example lim 1/n when n tend to infinity is 0, so how you can explain this to the computer ? and since the log function is a limit of a series of numerical functions so that's why you can't get the exact value .
Regards.Linux is not only an operating system, it's a philosophy.
Archost.
- 11-07-2007 #4That is incorrect.In maths infinite numbers exist but not in computers
You explain it thus:so for example lim 1/n when n tend to infinity is 0, so how you can explain this to the computer ?
The output:Code:#include <stdio.h> int main(void) { float alpha; float beta; float gamma; float n_infinity; float p_infinity; alpha=1.0; beta =0.0; p_infinity=alpha/beta; n_infinity=-p_infinity; printf(" infinity is printed as %f\n",p_infinity); printf("negative infinity is printed as %f\n",n_infinity); gamma=0.0; for(beta=1.0; gamma!=p_infinity; beta/=10.0 ) { gamma=alpha/beta; printf("%e %f\n",beta,gamma); } return 0; } /* main() */
Code:infinity is printed as inf negative infinity is printed as -inf 1.000000e+00 1.000000 1.000000e-01 10.000000 1.000000e-02 100.000000 9.999999e-04 1000.000061 9.999999e-05 10000.000977 9.999999e-06 100000.007812 9.999999e-07 1000000.125000 9.999999e-08 10000001.000000 9.999999e-09 100000008.000000 9.999999e-10 1000000128.000000 9.999999e-11 10000001024.000000 9.999999e-12 100000006144.000000 9.999999e-13 1000000126976.000000 9.999999e-14 10000000876544.000000 9.999999e-15 100000008765440.000000 9.999999e-16 1000000121208832.000000 9.999999e-17 10000001346306048.000000 9.999999e-18 100000007020609536.000000 9.999999e-19 1000000053026226176.000000 1.000000e-19 9999999980506447872.000000 1.000000e-20 100000002004087734272.000000 1.000000e-21 1000000020040877342720.000000 1.000000e-22 9999999778196308361216.000000 1.000000e-23 99999997781963083612160.000000 1.000000e-24 1000000013848427855085568.000000 1.000000e-25 9999999562023526247432192.000000 1.000000e-26 100000002537764290115403776.000000 1.000000e-27 999999988484154753734934528.000000 1.000000e-28 9999999442119689768320106496.000000 1.000000e-29 100000001504746621987668885504.000000 1.000000e-30 1000000015047466219876688855040.000000 1.000000e-31 10000000452706117102424182226944.000000 1.000000e-32 100000003318135351409612647563264.000000 9.999999e-34 1000000071866979741764260066230272.000000 9.999999e-35 10000000409184787596297531937521664.000000 9.999999e-36 100000004091847875962975319375216640.000000 9.999999e-37 1000000040918478759629753193752166400.000000 1.000000e-37 9999999933815812510711506376257961984.000000 9.999999e-39 100000006944061726476491472742798852096.000000 1.000000e-39 inf
That's part of the reason you can't get the exact value. Another part is that even among rational numbers, very few can be expressed exactly as floating point numbers. So when we run this:the log function is a limit of a series of numerical functions so that's why you can't get the exact value .
We get:Code:#include <stdio.h> int main(void) { float alpha; float beta; float gamma; alpha=1.0; beta =3.0; gamma=alpha/beta; printf("What we think is 1/3 is actually %25.20f\n",gamma); return 0; } /* main() */
And all we do when we extend the precision:Code:What we think is 1/3 is actually 0.33333334326744079590
is to buy us, well, a little more precision:Code:#include <stdio.h> int main(void) { double alpha; double beta; double gamma; alpha=1.0; beta =3.0; gamma=alpha/beta; printf("What we think is 1/3 is actually %25.20f\n",gamma); return 0; } /* main() */
Code:What we think is 1/3 is actually 0.33333333333333331483
- 11-08-2007 #5Linux is not only an operating system, it's a philosophy.
Archost.
- 11-08-2007 #6
I stand by what I wrote. I was trying to help, not to bash you in any way. The details:
"This", in post 3 and post 4 of this thread, was your statement:No this is correct
I am puzzled by your request:In maths infinite numbers exist but not in computers
because the link was not to an opinion, but to an explanation of how infinite numbers are represented (and, by implication, "exist") in computers. I thought that you and others might be interested in what that representation is, so I provided a link to a wikipedia article which discusses the way floating point numbers (including infinite ones) are represented.don't link me in other sites, put your opinions here
Was I presenting some sort of opinion? I don't see that, I'm sorry.
This is correct, in the same way that there is "just" a way to represent the number 3 or the number -5.infinite in computer is just a way to represent numbers
This is also correct.but the infinitesimal computing doesn't exist or it's only an with approach with a possible inconsistency
- 11-08-2007 #7Linux is not only an operating system, it's a philosophy.
Archost.
- 11-08-2007 #8
My attempt in this reply is to provide a little more information about floating point representation in computers. I hope this is of as much interest to aliov and others as it is to me.
I would be more inclined to say these four statements:there is no way to represent infinite numbers and infinitesimal computing without having errors unless you have an infinite memory
- There exist numbers which are sufficiently far from zero that their size prevents them from being represented precisely without using infinite memory.
I was going to say
but I opted for the slightly stronger statement, because in the IEEE 754 standard, even the number 1/3 cannot be represented precisely without using infinite memory.There exist numbers which are sufficiently far from zero that they cannot be represented precisely without using infinite memory. - There exist numbers which are sufficiently close to zero that their closeness to zero prevents them from being represented precisely without using infinite memory.
Same comment for this statement as for the previous one. - In the IEEE 754 standard for floating point numbers, there exist representations for both infinity and minus infinity.
- In the IEEE 754 standard for floating point numbers, there exists a representation for neither an infinitely small, nonzero positive number nor an infinitely small, nonzero negative number.
I was also going to say that I have learned a thing or two about computer science in my day, and I have the lab coat to prove it, but prudence prevents me.
- There exist numbers which are sufficiently far from zero that their size prevents them from being represented precisely without using infinite memory.
- 11-08-2007 #9Linux is not only an operating system, it's a philosophy.
Archost.
- 11-08-2007 #10Exactly.fortunately we have Linux around to allow us really to learn how the computer and the theories of computation have been established
I remember the first time I was presented with a shell prompt that gave me access to a C compiler on a system that was entirely unrelated to work.
I could play. I could play, with no apologies to anyone for how I spent my time.
Working has its rightful place, but playing can be an open-ended alternation between
andWow! That's how this works! That's how I can do this!
&^%$&%$*%$!!! SIGSEGV! Now what?--
Bill
Old age and treachery will overcome youth and skill.


Reply With Quote
