CGTalk Problem w/ expressions in C
 01-23-2004, 07:48 PM #1 singularity2006 Go this way; no that way!   I have odd jobs... many odd jobs... that don't pay?? ... ar?F   Join Date: Jan 2003 Posts: 3,817 Problem w/ expressions in C Code: ``` #include int main(void) { /*LOCAL DEFINITIONS*/ int a; int b; int c; float d; /*STATEMENTS: INPUTS*/ printf("please enter an integer value for a: "); scanf("%d", &a); printf("please enter an integer value for b: "); scanf("%d", &b); printf("please enter an integer value for c: "); scanf("%d", &c); printf("\na=%d, b=%d, c=%d\n", a, b, c); /*STATEMENTS: CALCULATIONS*/ d = a * b / c; /*STATEMENTS: OUTPUT*/ printf("\n\na * b / c = d = %.2f\n\n", d); }``` For some freakish reason, d keeps equalling 0!! What did I do wrong?? =( __________________ Best Regards, Chuck - Average Joe Freelancer Join the LifeSaverXP Cancer Research Team and make a difference, not just a donation. This is to everyone, family and friends - Cheers. Last edited by singularity2006 : 01-23-2004 at 07:54 PM. share quote
 01-23-2004, 09:32 PM #2 sbp Frequenter Scott Woods Spring Hill, USA   Join Date: Mar 2002 Posts: 112 int * int / int = int converted to float If the result is less than 1, then the result will be zero because the result is not converted to float until after it's calculated and the int type is whole numbers only. Cast either a b or c as a float in your calculation to convert the result in the calculation. d = (float)a * b / c; // works d = (float)a * (float)b / (float)c; // proper, but too much typing d = (float)(a * b / c) // bad because it's the same as the current line share quote
 01-23-2004, 11:03 PM #3 singularity2006 Go this way; no that way!   I have odd jobs... many odd jobs... that don't pay?? ... ar?F   Join Date: Jan 2003 Posts: 3,817 OooOH..... IC! Thanks, I'll give that a go. I figured there was something wrong w/ data types there. Btw, I'm curious about something, how many digits can a float number be as opposed to other data types? I can't seem to find any references for that. __________________ Best Regards, Chuck - Average Joe Freelancer Join the LifeSaverXP Cancer Research Team and make a difference, not just a donation. This is to everyone, family and friends - Cheers. share quote
 01-24-2004, 12:15 AM #4 playmesumch00ns Lord of the posts   render monkey pretty picture maker United Kingdom   Join Date: Jul 2002 Posts: 3,420 Read somewhere that float has 6 significant figures, while double has 10. They seemed confused about what a significant figure actually was though, so it might actually be 6 and 10 decimal places. There's an easy way to test this out though: #include #include int main() { float f = 1.123456789123456789123456789f double d = 1.123456789123456789123456789 std::cout << precision( 30 ) << f << endl; std::cout << precision( 30 ) << d << endl; return 0; } ... can't remember if it's precision() or setprecision() or something else like that, but you get the idea. __________________ You can have your characters photoreal, fast or cheap. Pick two. share quote
 01-24-2004, 05:45 AM #5 singularity2006 Go this way; no that way!   I have odd jobs... many odd jobs... that don't pay?? ... ar?F   Join Date: Jan 2003 Posts: 3,817 actually, are u familiar with scientific computations and how to find the correct number of significant figures? I've always wanted to figure out a way to produce a calculator that followed the correct logic. But it got really messy when I tried it in VB. What options do I have in C for that kind of dealy? This is only my third week in C so I don't know much... just printf and scanf. __________________ Best Regards, Chuck - Average Joe Freelancer Join the LifeSaverXP Cancer Research Team and make a difference, not just a donation. This is to everyone, family and friends - Cheers. share quote
 01-24-2004, 10:04 AM #6 playmesumch00ns Lord of the posts   render monkey pretty picture maker United Kingdom   Join Date: Jul 2002 Posts: 3,420 double post. sorry. __________________ You can have your characters photoreal, fast or cheap. Pick two. share quote
 01-24-2004, 10:05 AM #7 playmesumch00ns Lord of the posts   render monkey pretty picture maker United Kingdom   Join Date: Jul 2002 Posts: 3,420 Oops yeah the code I posted was C++. Sorry! A C translation would be Code: ``` main() { float f = 1.123456789123456789123456789f; double d = 1.123456789123456789123456789; printf( "Float: %.30f\nDouble: %.30f\n, f, d ); }``` I think.... Anyways, the maths fo significant figures... can't quite remember... GCSE was a while ago... 0.136 has 3 significant figures. 0.106 has 3 sf 0.016 has 2 sf. (or is it 3? this is where it gets tricky) Basically any number that's not a zero is a significant figure, unless the zero comes between two non-zero digits, in which case it is significant... but there's an exception... anyone care to help me out? I'm struggling... But anyway, floating point takes care of this all for you, since it's represented as a mantissa and an exponent, kinda like standard notation. __________________ You can have your characters photoreal, fast or cheap. Pick two. Last edited by playmesumch00ns : 01-24-2004 at 10:19 AM. share quote
 01-26-2004, 03:00 PM #8 markyjerky Frequenter   Join Date: Jan 2003 Posts: 256 I'll help write 0.016 as 1.6 x 10^(-2) Then you know that you are indicating 2 sig digits, if you are worried about that sort of thing. share quote
 01-26-2004, 08:17 PM #9 singularity2006 Go this way; no that way!   I have odd jobs... many odd jobs... that don't pay?? ... ar?F   Join Date: Jan 2003 Posts: 3,817 That is well and good, however, the rules for calculating significant figures are somewhat cumbersome to write in code through logic. Here's the idea: Addition and subtraction: 123.456 + 12.23 + 12.1 For addition and subtraction, the signficant digits are determined by the decimalThe 12.1 has only 1 decimal, which is considered the maximum number of decimals the answer may have. So the answer is 12.8. The idea is that you cannot have an answer more accurate than your least accurate measurement. Multiplication and division: 12.2 x 12.02 x 2.0 x 2 For multiplication and division, the significant digits are determined by the number with the fewest digits including decimals. 2.0 has 2 significant digits, but 2 only has one (no decimals). Therefore, the final answer cannot have more than 1 significant digit. The answer would thus be 600 How would you get that kind of logic into C? I was trying to get it in VB too but it was rather confusing. Anyone have any idea of how to program such a logic block? __________________ Best Regards, Chuck - Average Joe Freelancer Join the LifeSaverXP Cancer Research Team and make a difference, not just a donation. This is to everyone, family and friends - Cheers. share quote
 01-26-2004, 10:54 PM #10 markyjerky Frequenter   Join Date: Jan 2003 Posts: 256 I don't understand the "issue". I don't understand the "issue". Singularity ... you seem to have stated the domain logic quite well ... now seem like you just need a data structure. How exotic that would be depends on how much speed you need with these calculations ... you have not said much about that yet. Anyway ... if you just keep three parts intact after every operation ... 1) The characteristic 2) The exponent 3) The count of sig digits. Then the programming should be straight forward. You should be able to first lay out the problem in pseudo code ... as the real problem is not how to do this in "C". There would be zillions of approaches in C since it's quite up to the task. You could start with something like ... typedef struct temp_SIGDIG { short exponent; long long theCharacter; unsigned char nSigDig; } SigDigNumber; Float2Sig(float x, SigDigNumber* newNum); Double2Sig(float x, SigDigNumber* newNum); AddSigDigs(SigDigNumber* n1, SigDigNumber* n2); MultiplySigDigs(SigDigNumber* n1, SigDigNumber* n2); DivideSigDigs(SigDigNumber* n1, SigDigNumber* n2); Don't need Subtract I don't think as that's just a case of Add. I can't envision any of the above being tricky to write. share quote
 01-26-2004, 10:58 PM #11 markyjerky Frequenter   Join Date: Jan 2003 Posts: 256 If the Structure get's you down ... If the Structure get's you down ... Just start learning the bit operators in "C" and use various parts of a long long (8 bytes) to contain your characteristic, exponent, and sigs bit operators of & ~ | >> << to get at the goods you need. Then you can get rid of the pointers in the declarations ! share quote
 01-27-2004, 05:59 AM #12 singularity2006 Go this way; no that way!   I have odd jobs... many odd jobs... that don't pay?? ... ar?F   Join Date: Jan 2003 Posts: 3,817 I haven't learned enough C to program logic statements yet. I'm actually more interested in it for use in VB though. I can program that well enough to write ... sort of. Anyhow, this is more of a pet project at the moment than anything else. Thanks for the info. I'll give it a go again. For VB, my bog down point was when working with calculations with more than one variable. A lot of times there's a lot of user input for values a, b, c, and d (and more variables if the problem gets long), each with their own number of significant digits. So the way I looked @ it was that I would have to write up a case select or something of that sort to check the number of sig figs per variable and then have the program round off at the very end accordingly. It got weird because I'm not quite comfortable enough with recursion in this manner to check multiple variables over and over like that. __________________ Best Regards, Chuck - Average Joe Freelancer Join the LifeSaverXP Cancer Research Team and make a difference, not just a donation. This is to everyone, family and friends - Cheers. share quote
 01-27-2004, 07:46 AM #13 schmu_20mol Lord of the posts     Join Date: Mar 2002 Posts: 920 Code: ``` while (numbertocheck / a ) <= 1 do a := a * 10; INC (numberofdigits); END;``` this should work for you to check the number of digits for your variables - 'simply' make that a procedure you call with each variable. that's just pseudo-code so you'll have to get it into C yourself if you need it. actually i'm a bit confused about what you need so it may not fit you at all share quote
01-27-2004, 08:24 AM   #14
gga
Expert

Join Date: Jan 2003
Posts: 499
Quote:
 Originally posted by singularity2006 actually, are u familiar with scientific computations and how to find the correct number of significant figures? I've always wanted to figure out a way to produce a calculator that followed the correct logic. But it got really messy when I tried it in VB. What options do I have in C for that kind of dealy? This is only my third week in C so I don't know much... just printf and scanf.

And that's more or less all you'll need.
Read ALL the options of printf and sprintf:

printf("%2.e", 0.0004);

Will already deal with printing in scientific notation.

One of the interesting things is that floating point numbers are stored in a form of scientific notation inside the computer (which also does tend to create other precision headaches, too).

The float type contains 32 bits: 1 for the sign, 8 for the exponent, and 23 for the mantissa. Its range is +/– 3.4E38 with at least 7 digits of precision.

The double type contains 64 bits: 1 for the sign, 11 for the exponent, and 52 for the mantissa. Its range is +/– 1.7E308 with at least 15 digits of precision.

The long double type contains 80 bits: 1 for the sign, 15 for the exponent, and 64 for the mantissa. Its range is +/– 1.2E4932 with at least 19 digits of precision. With the Microsoft C compiler, the representation of type long double is identical to type double.
Long double is also hardly ever used in any code, particularly these days.

ANSI C afaik does not have a built-in standard function to count decimal digits of floating point numbers. But one could be implemented by turning the value into a string (see sprintf or _gcvt, _fcvt if non-standard ansi) and then counting the number of characters past the '.', disregarding trailing 0's (if a period is available, that is). If you look around the web, I'm sure you will find some code to do this somewhere.

Note that current Intel processors many times do floating point operations in up to 80 bits and the result is later truncated. This is another headache to deal (in addition to the IEEE fp standard) with when you actually want lack of precision. But these problems are not inherent to C but to modern computers in general.
If you want better control of floating point, there are free libraries available that offer more precision and their own floating point types by trading some speed. But you likely don't want to go there.

Last edited by gga : 01-27-2004 at 08:30 AM.

 01-17-2006, 07:00 AM #15 CGTalk Moderation Lord of the posts   Join Date: Sep 2003 Posts: 1,066,481 Thread automatically closed This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum. __________________ CGTalk Policy/Legalities Note that as CGTalk Members, you agree to the terms and conditions of using this website. share quote