English Amiga Board Why pow() is giving me this result?
 Register Amiga FAQ Rules & Help Members List  /  Moderators List Today's Posts Mark Forums Read

 03 July 2022, 09:51 #1 Sim085 Registered User   Join Date: Apr 2009 Location: N/A Posts: 904 Why pow() is giving me this result? (using vbcc in case this might be important for the question). I am trying to calculate the "power of" and print it on screen. However for some reason I get a different result if I print the result of the pow() directly or store the result of pow() in double variable and print the variable value. Here is the code: Code: double base, power, result; base = 2; power = 2; result = pow(base,power); printf("a: %.2lf b: %.2lf\n", result, pow(base,power)); The above code prints the following in the console: Code: a: 11-5./0400.00 b:4.01 I cannot understand why the results of a: and b: are different, they are the same pow() calculation with the only difference that a: shows the result which has been previously stored in a variable, and b: shows the result directly. The other thing I cannot understand is why the result of b: is 4.01 and not 4.0. In order to compile the solution I added the -lmieee flag. Would anyone know what is happening? When I try the same code using an online C compiler I get the expected result (a: 4.00 b: 4.00).
 03 July 2022, 10:14 #2 alkis Registered User   Join Date: Dec 2010 Location: Athens/Greece Age: 52 Posts: 702 You are using %lf in printf, try with %f See for example this https://stackoverflow.com/a/4264154/8390560
03 July 2022, 10:24   #3
jotd
This cat is no more

Join Date: Dec 2004
Location: FRANCE
Age: 51
Posts: 7,349
Quote:
 a: 11-5./0400.00
what is this output?

Check how pow is defined in your case. Is it returning a "float" or a "double"? if it returns a float, it's not going to end well with printf as %lf format is double (assigning in a double before hand solves the issue)

03 July 2022, 10:28   #4
Sim085
Registered User

Join Date: Apr 2009
Location: N/A
Posts: 904
Thank you alkis, doing this gives the following result:
Code:
a: 1074790400.00 b: 4.00
This resolved the 4.01 / 4.00 issue.

So this leaves only the question on why storing the pow() result in a variable of type double prints something completely different than printing the result of pow() directly?

Quote:
 Originally Posted by alkis You are using %lf in printf, try with %f See for example this https://stackoverflow.com/a/4264154/8390560

 03 July 2022, 10:37 #5 thomas Registered User   Join Date: Jan 2002 Location: Germany Posts: 6,818 Did you #include ? All those float/double functions only work correctly with proper prototypes. By default all parameters and results of functions are expected to be int and the compiler converts to/from float where it should not. It's even worse with double. The compiler converts to int and pushes 32 bits to the stack where the function expects a 64bit double. Only with prototyped functions the compiler knows what to do.
03 July 2022, 10:37   #6
Sim085
Registered User

Join Date: Apr 2009
Location: N/A
Posts: 904
I changed the code to float but still get same result:

Code:
float base, power, result;
base = 2; power = 2;
result = pow(base,power);
printf("a: %.2f b: %.2f\n", result, pow(base,power));
But this still gives the following result:

Code:
a: 1074790400.00 b: 4.00
When I check pow definition on the internet it takes two double parameters and returns a double which is why I was using double.

Quote:
 Originally Posted by jotd what is this output? Check how pow is defined in your case. Is it returning a "float" or a "double"? if it returns a float, it's not going to end well with printf as %lf format is double (assigning in a double before hand solves the issue)

03 July 2022, 10:42   #7
Sim085
Registered User

Join Date: Apr 2009
Location: N/A
Posts: 904
I missed that!

Confirm that using either double or float is giving correct result when I add the #include <math.h>.

Quote:
 Originally Posted by thomas Did you #include ? All those float/double functions only work correctly with proper prototypes. By default all parameters and results of functions are expected to be int and the compiler converts to/from float where it should not. It's even worse with double. The compiler converts to int and pushes 32 bits to the stack where the function expects a 64bit double. Only with prototyped functions the compiler knows what to do.

 03 July 2022, 10:43 #8 bebbo botcher   Join Date: Jun 2016 Location: Hamburg/Germany Posts: 657 well, it should print a: 4.00 b: 4.00 even without any includes. That should only cause warnings...
 03 July 2022, 11:08 #9 jotd This cat is no more   Join Date: Dec 2004 Location: FRANCE Age: 51 Posts: 7,349 If you don't include math.h, then the compiler assumes (after a shitload of warnings) Code: int pow(int a,int b); and it's not ending well. I don't see how you could even get 4 in the first place. don't leave any warnings in your code, that's a golden rule (that most software don't respect and get hell out of it)
03 July 2022, 11:28   #10
Sim085
Registered User

Join Date: Apr 2009
Location: N/A
Posts: 904
To be fair I only started to get a warning when I used pow() directly in the printf and was ignorning it as had only added that in the printf to quick "debug" what was happening. The following does not give any warnings when not including #include <math.h> but the result is still wrong.
Code:
double result = pow(base,power);
printf("result: %.2f\n", result);
prints:

Code:
result: 1074790400.00

Quote:
 Originally Posted by jotd If you don't include math.h, then the compiler assumes (after a shitload of warnings) Code: int pow(int a,int b); and it's not ending well. I don't see how you could even get 4 in the first place. don't leave any warnings in your code, that's a golden rule (that most software don't respect and get hell out of it)

03 July 2022, 11:34   #11
thomas
Registered User

Join Date: Jan 2002
Location: Germany
Posts: 6,818
Quote:
 Originally Posted by Sim085 To be fair I only started to get a warning when
Add -warn=-1 to the vbcc command line and -dontwarn= only for those you really don't need.

03 July 2022, 12:36   #12
phx
Natteravn

Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,347
As far as I can see the behaviour shown here is absolutely to be expected.
1. %lf and %f should make no difference. printf-like functions always take double precision arguments for float. An exception would be %Lf for long double, but on m68k this is the same as double.
2. ISO-C defines that the return value of unknown functions, without a prototype, use the type
int
. The arguments of such a function are simply pushed by using the argument's type, promoted to
int
, if smaller (e.g. char or short). So the arguments for
pow()
are ok. The return value is garbage.
What happened here in detail, is this:
• result = pow(base, power)
correctly calculates the power of 2.0 and 2.0, but as the return type of pow is unknown, is is assumed as
int
.
• As you are assigning the result of the "int" function to a double variable, it is then converted to double. The double precision result was \$4010000000000000, with \$40100000 in D0, which is 1074790400 and being converted to float. Sounds familiar?
• Now
pow(base, power)
is called again, to calculate the last argument of
printf()
. Again the result is assumed as int and only the 32-bit word of \$40100000 (MSW of the result) is pushed onto the stack. Next pushed on the stack are the 64 bits from
result
, and finally the format string pointer.
When printf is called is fetches a double argument for the first %f, which is 1074890400.0 (see above). Then is fetches another double argument for the second %f, which is \$40100000 and a random 32-bit word from the stack. This random value modifies the mantissa enough to get small deviations, like 4.01 or 4.02.

All caused by missing the prototype for pow()!

Quote:
 Originally Posted by bebbo well, it should print a: 4.00 b: 4.00 even without any includes.
No, it shouldn't. At least not according to ISO-C. Maybe gcc recognizes some math functions automatically? But then it certainly doesn't work for new floating point functions.

Quote:
 Originally Posted by Sim085 The following does not give any warnings when not includin Code: double result = pow(base,power); printf("result: %.2f\n", result);
It definitely does. Show me the full the source where it doesn't. Here is mine:
Code:
frank@altair cat tst.c
int main()
{
double base = 2;
double power = 2;
double result = pow(base,power);
printf("result: %.2f\n", result);
return 0;
}
frank@altair vc +aos68k -o tst tst.c -lmieee
>    double result = pow(base,power);
warning 161 in line 5 of "tst.c": implicit declaration of function <pow>
>    printf("result: %.2f\n", result);
warning 161 in line 6 of "tst.c": implicit declaration of function <printf>
>    printf("result: %.2f\n", result);
warning 213 in line 6 of "tst.c": varargs function called without prototype in scope

03 July 2022, 12:54   #13
Sim085
Registered User

Join Date: Apr 2009
Location: N/A
Posts: 904
Quote:
 Originally Posted by phx As far as I can see the behaviour shown here is absolutely to be expected.
Thank you for the detailed explanation. Now I understand better what is happening in the background.

Quote:
 It definitely does. Show me the full the source where it doesn't. Here is mine:
After thomas comment I checked my make file and I do not have any warning flags included.

What are the suggested -dontwarn values to use?

Just adding -warn=-1 floods the compiler with warnings and many (sorry if saying so sound blasphemes ) do not seem to be important or referring to libraries I am using not wrote myself. Here are some examples:

Code:
struct Process *myProcess = NULL;
no deceleration of global variable <myProcess> before definition.
...
"dos/notify.h": member <nr_Reserved> does not have natural alignment.

03 July 2022, 13:23   #14
phx
Natteravn

Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,347
Quote:
 Originally Posted by Sim085 After thomas comment I checked my make file and I do not have any warning flags included.
Neither do I. You see my call to the vc-frontend above.

Quote:
 What are the suggested -dontwarn values to use?
None. The default settings are usually fine.

Sometimes you want to use
-dontwarn=
for compiling bad source texts, or very old ones using K&R syntax, before you have to fix everything in it. For you own sources you should never suppress warnings, but fix them.

Quote:
 Just adding -warn=-1 floods the compiler with warnings
Not sure why Thomas suggested it. IMHO it makes no sense.
Just use the default settings.

 03 July 2022, 17:59 #15 paraj Registered User   Join Date: Feb 2017 Location: Denmark Posts: 571 As already mentioned it's highly adviceable to at least use the default warning level with your compiler. I usually go further, like thomas, and enable nearly every warning and then selectively disable the ones I don't want. Another tip is to make sure (most of) your code can be compiled with multiple compilers as they often catch different things. VBCC is of course conformant here, and it's a classic mistake that's even covered by the comp.lang.c FAQ. (Not that I blame OP, I'm sure we've all made it) Sidenote MSVC (19.32) outputs 0.00/0.00 when compiling without optimizations but 4.0/4.0 with for the original code indication "special knowledge" of certain functions (as allowed by the standard).
 03 July 2022, 21:43 #16 Sim085 Registered User   Join Date: Apr 2009 Location: N/A Posts: 904 I have written this code in a separate solution and the only warning I am getting is in relation to vargs. My code is as follows: Code: int main() { double base = 2; double power = 2; double result = pow(base,power); printf("result: %.2f\n", result); return 0; } My make file is as follows: Code: CC=vc +aos68k COPT = LIBS = -lamiga -lauto -lmieee %.o : %.c \$(CC) \$(COPT) -c \$< -o \$@ HelloWorld : main.o \$(CC) \$^ -o \$@ \$(LIBS) main.o: main.h (left COPT empty). I have tested this on vbcc version vbcc 0.904 (30.12.2014). Since this looks old I installed the latest one I could find on aminet, however, also on vbcc 0.907 (03.10.2019) I do not get any warning when using pow() without prototype. Is something wrong with my setup? Everything compiles and I do get a warning, but not this particular one in relation to pow()
03 July 2022, 23:14   #17
phx
Natteravn

Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,347
Quote:
 Originally Posted by Sim085 also on vbcc 0.907 (03.10.2019) I do not get any warning when using pow() without prototype.
Wow... you're right! I just tested some old versions, including V0.9g, and these warnings are indeed missing with default settings.

Seems that they were made the default only with this year's release, V0.9h. So you may either want to update, or use
-warn=161
to enable it in older versions.

 06 July 2022, 16:39 #18 Sim085 Registered User   Join Date: Apr 2009 Location: N/A Posts: 904 Wanted to thank everyone for all the help. Have installed latest version and am getting some warnings in other areas which I am looking at. Many thanks

 Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 Similar Threads Thread Thread Starter Forum Replies Last Post thomas support.WinUAE 1 23 December 2016 20:18 ramonsmits support.Hardware 10 10 November 2015 20:26 Maren support.WinUAE 3 02 January 2011 08:32 wilshy Retrogaming General Discussion 6 22 October 2009 20:27 Unregistered New to Emulation or Amiga scene 2 16 December 2001 20:31

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is Off Forum Rules
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home News Main     Amiga scene     Retrogaming General Discussion     Nostalgia & memories Support     New to Emulation or Amiga scene         Member Introductions     support.WinUAE     support.WinFellow     support.OtherUAE     support.FS-UAE         project.AmigaLive     support.Hardware         Hardware mods         Hardware pics     support.Games     support.Demos     support.Apps     support.Amiga Forever     support.Amix     support.AmigaOS     support.Other Requests     request.UAE Wishlist     request.Old Rare Games     request.Demos     request.Apps     request.Modules     request.Music     request.Other     Looking for a game name ?     Games images which need to be WHDified abime.net - Hall Of Light     HOL news     HOL suggestions and feedback     HOL data problems     HOL contributions abime.net - Amiga Magazine Rack     AMR news     AMR suggestions and feedback     AMR data problems     AMR contributions abime.net - Home Projects     project.Amiga Lore     project.EAB     project.IRC     project.Mods Jukebox     project.Wiki abime.net - Hosted Projects     project.aGTW     project.APoV     project.ClassicWB     project.Jambo!     project.Green Amiga Alien GUIDES     project.Maptapper     project.Sprites     project.WinUAE - Kaillera Other Projects     project.Amiga Demo DVD     project.Amiga Game Factory     project.CARE     project.Amiga File Server     project.CD32 Conversion     project.Game Cover Art         GCA.Feedback and Suggestions         GCA.Work in Progress         GCA.Cover Requests         GCA.Usefull Programs         GCA.Helpdesk     project.KGLoad     project.MAGE     project.Missing Full Shareware Games     project.SPS (was CAPS)     project.TOSEC (amiga only)     project.WHDLoad         project.Killergorilla's WHD packs Misc     Amiga websites reviews     MarketPlace         Swapshop     Kinky Amiga Stuff     Collections     EAB's competition Coders     Coders. General         Coders. Releases         Coders. Tutorials     Coders. Asm / Hardware     Coders. System         Coders. Scripting         Coders. Nextgen     Coders. Language         Coders. C/C++         Coders. AMOS         Coders. Blitz Basic     Coders. Contest         Coders. Entries Creation     Graphics         Graphics. Work In Progress         Graphics. Finished Work         Graphics. Tutorials     Music         Music. Work In Progress         Music. Finished Work         Music. Tutorials

All times are GMT +2. The time now is 17:06.

 -- EAB3 skin ---- EAB2 skin ---- Mobile skin Archive - Top