Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
07-02-2024, 01:35 PM
|
#1
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
|
calculating lists of dollar amounts (off by a few pennys) ?
ennee way ī ken get this code to act rite ?:
Code:
schneidz@lq> cat s.c
#include <stdio.h>
main()
{
int i;
float s = 4.18;
i = s * 100;
printf("float s = %f :: int i (s x 100) = %d\n", s, i);
}
schneidz@lq> a.out
float s = 4.180000 :: int i (s x 100) = 417
|
|
|
07-02-2024, 01:52 PM
|
#2
|
Senior Member
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,185
|
You are trying to toss a float to an int. Try this
Code:
#include <stdio.h>
int main()
{
float a = 0.0;
float s = 4.18;
a = s * 100;
printf("float s = %.2f :: float a ( s * 100) = %.0f\n", s, a);
}
This will output the value as a float without any decimal places. It's lost in the cast. Why is above my pay grade. This outputs the (assumed) expected data.
Code:
#include <stdio.h>
int main()
{
float a = 4.18;
printf("float a (%.2f * 100) = %.2f\n", a, a * 100);
}
For the memory conscious. No reason to allocate a variable, small as it may be if you can avoid it I'd think. yes I'm talking out of my ass.
Last edited by jmgibson1981; 07-02-2024 at 01:59 PM.
|
|
2 members found this post helpful.
|
07-02-2024, 02:03 PM
|
#3
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
Original Poster
|
Quote:
Originally Posted by jmgibson1981
You are trying to toss a float to an int. Try this
Code:
#include <stdio.h>
int main()
{
float a = 0.0;
float s = 4.18;
a = s * 100;
printf("float s = %.2f :: float a ( s * 100) = %.0f\n", s, a);
}
This will output the value as a float without any decimal places. It's lost in the cast. Why is above my pay grade. This outputs the (assumed) expected data.
|
thanks but,...
my real code was comparing sprintf(str, "%4.2f", s) strings but some records were still off a few pennys so my new plan is to multiply those columns by 100.
i see a few records where the multiplication is obviously wrong (e.g.: 4.18) so i am now reaching for a better strategy ?
_____
basically my question is how to total up a few thousand dollar amounts from the 4th column of a file and compare the cumulative amount to 75431.31.
if they are equal, then do nothing.
if they are different, then print out: "mismatch: %4.2f" %4.2f".
i keep getting errors like:
Code:
col4sum (116448.27) does not match total (116448.29)
col4sum (81986.13) does not match total (81986.12)
Last edited by schneidz; 07-02-2024 at 02:15 PM.
|
|
|
07-02-2024, 02:35 PM
|
#4
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
Original Poster
|
i changed this line and the outputs are more sane now for the exceptionally large groupings:
Code:
schneidz@lq diff era-execute-2024-07-01.c era-execute.c
85c85
< sprintf(col4sum, "%4.2f",strtof(col4sum, NULL) + strtof(col4, NULL));
---
> sprintf(col4sum, "%4.2f",strtod(col4sum, NULL) + strtod(col4, NULL));
Last edited by schneidz; 07-02-2024 at 02:39 PM.
|
|
|
07-02-2024, 02:45 PM
|
#5
|
Moderator
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,295
|
jmgibson1981 is correct, you cannot toss a float into an integer as in the example code without loss! The compiler will implicitly round and truncate for you, but you always lose "something".
But in general not all numbers can be exactly represented as a float anyway. Try using a double instead in your example and you will likely get what you are after - in this specfic case, but not all cases because not all numbers can be represented as a double either! Next up would be long double which pushes the limit much further to the right* (but it is still there!).
That said, for working with monetary values, i.e. two decimal places, doubles should be sufficient. Multiplying by 100 to get an intermediate result only introduces another potential rounding error.
For absolute exact numeric results look into arbitrary precision and integer math.
*(Further to the right in the representation, i.e. precision, not same as the number of decimal places you can work with, so as to not mislead!)
Last edited by astrogeek; 07-02-2024 at 03:28 PM.
|
|
1 members found this post helpful.
|
07-02-2024, 02:50 PM
|
#6
|
Senior Member
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,185
|
Quote:
thanks but,...
my real code was comparing sprintf(str, "%4.2f", s) strings but some records were still off a few pennys so my new plan is to multiply those columns by 100.
|
Doubles are the better choice but if you want an answer to that, which is a bit of a different thing then you need to post the actual code in question. Can only reply to what we see.
|
|
1 members found this post helpful.
|
07-02-2024, 03:40 PM
|
#7
|
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,924
|
As it has been already said, floating point calculations are inaccurate by design; an option is storing cents (pennies) in integer variables. In a 64-bit 'long' variable you can store up to 90000 billion euros this way (9*10^16)
|
|
1 members found this post helpful.
|
07-02-2024, 06:19 PM
|
#8
|
Senior Member
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,793
|
For reference: https://floating-point-gui.de/
Quote:
What Every Programmer Should Know About Floating-Point Arithmetic
or
Why don’t my numbers add up?
|
|
|
2 members found this post helpful.
|
All times are GMT -5. The time now is 05:17 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|