LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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


Reply
  Search this Thread
Old 07-02-2024, 01:35 PM   #1
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326

Rep: Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919
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
 
Old 07-02-2024, 01:52 PM   #2
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,185

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
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.
Old 07-02-2024, 02:03 PM   #3
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326

Original Poster
Rep: Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919
Quote:
Originally Posted by jmgibson1981 View Post
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.
 
Old 07-02-2024, 02:35 PM   #4
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326

Original Poster
Rep: Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919Reputation: 919
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.
 
Old 07-02-2024, 02:45 PM   #5
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,295
Blog Entries: 24

Rep: Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254Reputation: 4254
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.
Old 07-02-2024, 02:50 PM   #6
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,185

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
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.
Old 07-02-2024, 03:40 PM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,924
Blog Entries: 1

Rep: Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886Reputation: 1886
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.
Old 07-02-2024, 06:19 PM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,793

Rep: Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087Reputation: 2087
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.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
FireStarter lists IP blocked that etherape lists as connections??? theKbStockpiler Linux - Security 1 09-26-2017 09:24 PM
LXer: Python - Sorting Lists inside of Lists LXer Syndicated Linux News 0 06-06-2013 01:00 PM
How are opt-in e-mail lists distinguished from spam lists? Travis86 Programming 2 01-29-2012 08:55 PM
LXer: Unique Sorting Of Lists And Lists Of Lists With Perl For Linux Or Unix LXer Syndicated Linux News 0 09-05-2008 01:50 PM
rm command is choking on large amounts of data? Jello Linux - General 18 02-28-2003 07:11 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:17 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration