script in C is not adding Floats correctly
This is my first time posting here so this post might be a little bit of a mess but I'll try my best to explain everything.
I have to make a program that acts kinda like Self-checkout in a store.
However i run into two issues when people are inserting money into the machine.
People insert money like this:
10 20 50 0.10 .... and the paying ends with 0 or by using ctrl+d.
(people can only use coins of this value: 100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05, 0.02 a 0.01 as you can see in the code)
Well when I end the payment with 0 program exits normally.(like this: 50 20 0)
However when I end it with ctrl+d it causes infinite loop and i don't understand why.
And the second issue is that for some reason it won't add numbers like 0.10, 0.20 and so on. Any ideas how to fix this or what might be causing the error?
And dont mind the printf in the middle that was just me checking the value.
float bill,x,payment=0,k=0;
printf("coins ");
while(k==0)
{
scanf("%f", &x);
if(x==0 )
{
goto END;
}
if(x ==100 || x ==50 || x ==20 || x ==10 || x ==5 || x ==2 || x ==1 || x ==0.50 || x==0.10 || x ==0.20 || x ==0.05 || x ==0.02|| x ==0.01 )
{
payment += x;
printf("==============");
printf("%.2f n",payment);
}
else{
printf("%.2f is invalid",x);
k = 1;
goto END2;
}
}
END:
printf("%.2f n", payment);
END2:
return 0;
c while-loop floating-point
|
show 2 more comments
This is my first time posting here so this post might be a little bit of a mess but I'll try my best to explain everything.
I have to make a program that acts kinda like Self-checkout in a store.
However i run into two issues when people are inserting money into the machine.
People insert money like this:
10 20 50 0.10 .... and the paying ends with 0 or by using ctrl+d.
(people can only use coins of this value: 100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05, 0.02 a 0.01 as you can see in the code)
Well when I end the payment with 0 program exits normally.(like this: 50 20 0)
However when I end it with ctrl+d it causes infinite loop and i don't understand why.
And the second issue is that for some reason it won't add numbers like 0.10, 0.20 and so on. Any ideas how to fix this or what might be causing the error?
And dont mind the printf in the middle that was just me checking the value.
float bill,x,payment=0,k=0;
printf("coins ");
while(k==0)
{
scanf("%f", &x);
if(x==0 )
{
goto END;
}
if(x ==100 || x ==50 || x ==20 || x ==10 || x ==5 || x ==2 || x ==1 || x ==0.50 || x==0.10 || x ==0.20 || x ==0.05 || x ==0.02|| x ==0.01 )
{
payment += x;
printf("==============");
printf("%.2f n",payment);
}
else{
printf("%.2f is invalid",x);
k = 1;
goto END2;
}
}
END:
printf("%.2f n", payment);
END2:
return 0;
c while-loop floating-point
3
You should check the return value of scanf, expecially if you want to "end it with ctrl+d".
– Bob__
Nov 24 '18 at 22:17
I wanted to point out the same as @Bob__ did cplusplus.com/reference/cstdio/scanf the scanf function can fail and you do not consider it.
– petrch
Nov 24 '18 at 22:18
2
You would be better off keeping the money in pennies rather than using floating point for fractions.
– Retired Ninja
Nov 24 '18 at 22:38
Yeah, It could be said, that never use floating point numbers for money (unless you intentionally want rounding errors to add up to visible amounts...).
– hyde
Nov 24 '18 at 22:40
@hyde: First, there are decimal floating-point formats in both hardware (including Intel and IBM) and software (including Microsoft) that are perfectly fine for doing the kind of currency calculations shown in this question. So the advice never to use floating-point for money is wrong on that count. Second, floating-point formats, whether binary or decimal, are appropriate for working on financial calculations such as stock market option evaluation, properly designed mortgage calculations, or even calculating sales taxes when done correctly.
– Eric Postpischil
Nov 25 '18 at 0:30
|
show 2 more comments
This is my first time posting here so this post might be a little bit of a mess but I'll try my best to explain everything.
I have to make a program that acts kinda like Self-checkout in a store.
However i run into two issues when people are inserting money into the machine.
People insert money like this:
10 20 50 0.10 .... and the paying ends with 0 or by using ctrl+d.
(people can only use coins of this value: 100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05, 0.02 a 0.01 as you can see in the code)
Well when I end the payment with 0 program exits normally.(like this: 50 20 0)
However when I end it with ctrl+d it causes infinite loop and i don't understand why.
And the second issue is that for some reason it won't add numbers like 0.10, 0.20 and so on. Any ideas how to fix this or what might be causing the error?
And dont mind the printf in the middle that was just me checking the value.
float bill,x,payment=0,k=0;
printf("coins ");
while(k==0)
{
scanf("%f", &x);
if(x==0 )
{
goto END;
}
if(x ==100 || x ==50 || x ==20 || x ==10 || x ==5 || x ==2 || x ==1 || x ==0.50 || x==0.10 || x ==0.20 || x ==0.05 || x ==0.02|| x ==0.01 )
{
payment += x;
printf("==============");
printf("%.2f n",payment);
}
else{
printf("%.2f is invalid",x);
k = 1;
goto END2;
}
}
END:
printf("%.2f n", payment);
END2:
return 0;
c while-loop floating-point
This is my first time posting here so this post might be a little bit of a mess but I'll try my best to explain everything.
I have to make a program that acts kinda like Self-checkout in a store.
However i run into two issues when people are inserting money into the machine.
People insert money like this:
10 20 50 0.10 .... and the paying ends with 0 or by using ctrl+d.
(people can only use coins of this value: 100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05, 0.02 a 0.01 as you can see in the code)
Well when I end the payment with 0 program exits normally.(like this: 50 20 0)
However when I end it with ctrl+d it causes infinite loop and i don't understand why.
And the second issue is that for some reason it won't add numbers like 0.10, 0.20 and so on. Any ideas how to fix this or what might be causing the error?
And dont mind the printf in the middle that was just me checking the value.
float bill,x,payment=0,k=0;
printf("coins ");
while(k==0)
{
scanf("%f", &x);
if(x==0 )
{
goto END;
}
if(x ==100 || x ==50 || x ==20 || x ==10 || x ==5 || x ==2 || x ==1 || x ==0.50 || x==0.10 || x ==0.20 || x ==0.05 || x ==0.02|| x ==0.01 )
{
payment += x;
printf("==============");
printf("%.2f n",payment);
}
else{
printf("%.2f is invalid",x);
k = 1;
goto END2;
}
}
END:
printf("%.2f n", payment);
END2:
return 0;
c while-loop floating-point
c while-loop floating-point
edited Dec 1 '18 at 0:37
Thomas
asked Nov 24 '18 at 22:08
ThomasThomas
83
83
3
You should check the return value of scanf, expecially if you want to "end it with ctrl+d".
– Bob__
Nov 24 '18 at 22:17
I wanted to point out the same as @Bob__ did cplusplus.com/reference/cstdio/scanf the scanf function can fail and you do not consider it.
– petrch
Nov 24 '18 at 22:18
2
You would be better off keeping the money in pennies rather than using floating point for fractions.
– Retired Ninja
Nov 24 '18 at 22:38
Yeah, It could be said, that never use floating point numbers for money (unless you intentionally want rounding errors to add up to visible amounts...).
– hyde
Nov 24 '18 at 22:40
@hyde: First, there are decimal floating-point formats in both hardware (including Intel and IBM) and software (including Microsoft) that are perfectly fine for doing the kind of currency calculations shown in this question. So the advice never to use floating-point for money is wrong on that count. Second, floating-point formats, whether binary or decimal, are appropriate for working on financial calculations such as stock market option evaluation, properly designed mortgage calculations, or even calculating sales taxes when done correctly.
– Eric Postpischil
Nov 25 '18 at 0:30
|
show 2 more comments
3
You should check the return value of scanf, expecially if you want to "end it with ctrl+d".
– Bob__
Nov 24 '18 at 22:17
I wanted to point out the same as @Bob__ did cplusplus.com/reference/cstdio/scanf the scanf function can fail and you do not consider it.
– petrch
Nov 24 '18 at 22:18
2
You would be better off keeping the money in pennies rather than using floating point for fractions.
– Retired Ninja
Nov 24 '18 at 22:38
Yeah, It could be said, that never use floating point numbers for money (unless you intentionally want rounding errors to add up to visible amounts...).
– hyde
Nov 24 '18 at 22:40
@hyde: First, there are decimal floating-point formats in both hardware (including Intel and IBM) and software (including Microsoft) that are perfectly fine for doing the kind of currency calculations shown in this question. So the advice never to use floating-point for money is wrong on that count. Second, floating-point formats, whether binary or decimal, are appropriate for working on financial calculations such as stock market option evaluation, properly designed mortgage calculations, or even calculating sales taxes when done correctly.
– Eric Postpischil
Nov 25 '18 at 0:30
3
3
You should check the return value of scanf, expecially if you want to "end it with ctrl+d".
– Bob__
Nov 24 '18 at 22:17
You should check the return value of scanf, expecially if you want to "end it with ctrl+d".
– Bob__
Nov 24 '18 at 22:17
I wanted to point out the same as @Bob__ did cplusplus.com/reference/cstdio/scanf the scanf function can fail and you do not consider it.
– petrch
Nov 24 '18 at 22:18
I wanted to point out the same as @Bob__ did cplusplus.com/reference/cstdio/scanf the scanf function can fail and you do not consider it.
– petrch
Nov 24 '18 at 22:18
2
2
You would be better off keeping the money in pennies rather than using floating point for fractions.
– Retired Ninja
Nov 24 '18 at 22:38
You would be better off keeping the money in pennies rather than using floating point for fractions.
– Retired Ninja
Nov 24 '18 at 22:38
Yeah, It could be said, that never use floating point numbers for money (unless you intentionally want rounding errors to add up to visible amounts...).
– hyde
Nov 24 '18 at 22:40
Yeah, It could be said, that never use floating point numbers for money (unless you intentionally want rounding errors to add up to visible amounts...).
– hyde
Nov 24 '18 at 22:40
@hyde: First, there are decimal floating-point formats in both hardware (including Intel and IBM) and software (including Microsoft) that are perfectly fine for doing the kind of currency calculations shown in this question. So the advice never to use floating-point for money is wrong on that count. Second, floating-point formats, whether binary or decimal, are appropriate for working on financial calculations such as stock market option evaluation, properly designed mortgage calculations, or even calculating sales taxes when done correctly.
– Eric Postpischil
Nov 25 '18 at 0:30
@hyde: First, there are decimal floating-point formats in both hardware (including Intel and IBM) and software (including Microsoft) that are perfectly fine for doing the kind of currency calculations shown in this question. So the advice never to use floating-point for money is wrong on that count. Second, floating-point formats, whether binary or decimal, are appropriate for working on financial calculations such as stock market option evaluation, properly designed mortgage calculations, or even calculating sales taxes when done correctly.
– Eric Postpischil
Nov 25 '18 at 0:30
|
show 2 more comments
3 Answers
3
active
oldest
votes
When you send Ctrl+D
in your terminal, you register an EOF
character to stdin
, therefore scanf
won't read anything anymore, and x
will never be set to 0
, so you won't escape your loop.
You would need to check the result of scanf
, reading man scanf
you can see that you are expecting a return value > 0 in case of success.
if (scanf("%f", &x) < 1 || x = 0) // Check return value of scanf, then check x
GOTO: END;
Edit:
Note that if scanf
was reading input items, you would need to check that the return value of scanf
is not less that the number of input items.
This will also work if you have a read error; you could really get fancy by checking iferrno
is set onEND
andperror
.
– Neil Edelman
Nov 24 '18 at 22:32
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
add a comment |
Fixing this answer based on hyde's and alamit's comments
The reason your program "refuses" to add small numbers like 0.10 is because your variable x
and the decimal literals like 0.10
you are comparing it to have different precision.
So, to fix the problem, add f
to the values x == 0.10f
, or switch to using double
and reading and printing with %lf
If you want to know the math behind the problem, read this.
1
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
1
The issue comes from comparingfloat
withdouble
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use0.1f
for example.
– alamit
Nov 24 '18 at 22:49
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").
– hyde
Nov 24 '18 at 22:56
|
show 1 more comment
When making comparisons with floating point numbers, one must be careful. Floating point representation of 0.1
is different between 32 bits and 64 bits(float
vs double
). You have defined x to be float
which is compared with 0.1(which is double
). So the comparison will not work correctly. Either you must define x as double
and change nothing else in your code or, make x == 0.1
to x == 0.1f
Further information about this topic can be found this answer and this topic
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462772%2fscript-in-c-is-not-adding-floats-correctly%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
When you send Ctrl+D
in your terminal, you register an EOF
character to stdin
, therefore scanf
won't read anything anymore, and x
will never be set to 0
, so you won't escape your loop.
You would need to check the result of scanf
, reading man scanf
you can see that you are expecting a return value > 0 in case of success.
if (scanf("%f", &x) < 1 || x = 0) // Check return value of scanf, then check x
GOTO: END;
Edit:
Note that if scanf
was reading input items, you would need to check that the return value of scanf
is not less that the number of input items.
This will also work if you have a read error; you could really get fancy by checking iferrno
is set onEND
andperror
.
– Neil Edelman
Nov 24 '18 at 22:32
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
add a comment |
When you send Ctrl+D
in your terminal, you register an EOF
character to stdin
, therefore scanf
won't read anything anymore, and x
will never be set to 0
, so you won't escape your loop.
You would need to check the result of scanf
, reading man scanf
you can see that you are expecting a return value > 0 in case of success.
if (scanf("%f", &x) < 1 || x = 0) // Check return value of scanf, then check x
GOTO: END;
Edit:
Note that if scanf
was reading input items, you would need to check that the return value of scanf
is not less that the number of input items.
This will also work if you have a read error; you could really get fancy by checking iferrno
is set onEND
andperror
.
– Neil Edelman
Nov 24 '18 at 22:32
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
add a comment |
When you send Ctrl+D
in your terminal, you register an EOF
character to stdin
, therefore scanf
won't read anything anymore, and x
will never be set to 0
, so you won't escape your loop.
You would need to check the result of scanf
, reading man scanf
you can see that you are expecting a return value > 0 in case of success.
if (scanf("%f", &x) < 1 || x = 0) // Check return value of scanf, then check x
GOTO: END;
Edit:
Note that if scanf
was reading input items, you would need to check that the return value of scanf
is not less that the number of input items.
When you send Ctrl+D
in your terminal, you register an EOF
character to stdin
, therefore scanf
won't read anything anymore, and x
will never be set to 0
, so you won't escape your loop.
You would need to check the result of scanf
, reading man scanf
you can see that you are expecting a return value > 0 in case of success.
if (scanf("%f", &x) < 1 || x = 0) // Check return value of scanf, then check x
GOTO: END;
Edit:
Note that if scanf
was reading input items, you would need to check that the return value of scanf
is not less that the number of input items.
edited Nov 24 '18 at 22:38
answered Nov 24 '18 at 22:27
alamitalamit
36719
36719
This will also work if you have a read error; you could really get fancy by checking iferrno
is set onEND
andperror
.
– Neil Edelman
Nov 24 '18 at 22:32
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
add a comment |
This will also work if you have a read error; you could really get fancy by checking iferrno
is set onEND
andperror
.
– Neil Edelman
Nov 24 '18 at 22:32
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
This will also work if you have a read error; you could really get fancy by checking if
errno
is set on END
and perror
.– Neil Edelman
Nov 24 '18 at 22:32
This will also work if you have a read error; you could really get fancy by checking if
errno
is set on END
and perror
.– Neil Edelman
Nov 24 '18 at 22:32
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
Thanks for the answer. It works perfectly.
– Thomas
Nov 25 '18 at 0:25
add a comment |
Fixing this answer based on hyde's and alamit's comments
The reason your program "refuses" to add small numbers like 0.10 is because your variable x
and the decimal literals like 0.10
you are comparing it to have different precision.
So, to fix the problem, add f
to the values x == 0.10f
, or switch to using double
and reading and printing with %lf
If you want to know the math behind the problem, read this.
1
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
1
The issue comes from comparingfloat
withdouble
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use0.1f
for example.
– alamit
Nov 24 '18 at 22:49
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").
– hyde
Nov 24 '18 at 22:56
|
show 1 more comment
Fixing this answer based on hyde's and alamit's comments
The reason your program "refuses" to add small numbers like 0.10 is because your variable x
and the decimal literals like 0.10
you are comparing it to have different precision.
So, to fix the problem, add f
to the values x == 0.10f
, or switch to using double
and reading and printing with %lf
If you want to know the math behind the problem, read this.
1
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
1
The issue comes from comparingfloat
withdouble
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use0.1f
for example.
– alamit
Nov 24 '18 at 22:49
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").
– hyde
Nov 24 '18 at 22:56
|
show 1 more comment
Fixing this answer based on hyde's and alamit's comments
The reason your program "refuses" to add small numbers like 0.10 is because your variable x
and the decimal literals like 0.10
you are comparing it to have different precision.
So, to fix the problem, add f
to the values x == 0.10f
, or switch to using double
and reading and printing with %lf
If you want to know the math behind the problem, read this.
Fixing this answer based on hyde's and alamit's comments
The reason your program "refuses" to add small numbers like 0.10 is because your variable x
and the decimal literals like 0.10
you are comparing it to have different precision.
So, to fix the problem, add f
to the values x == 0.10f
, or switch to using double
and reading and printing with %lf
If you want to know the math behind the problem, read this.
edited Nov 24 '18 at 23:04
answered Nov 24 '18 at 22:36
Lev M.Lev M.
628112
628112
1
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
1
The issue comes from comparingfloat
withdouble
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use0.1f
for example.
– alamit
Nov 24 '18 at 22:49
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").
– hyde
Nov 24 '18 at 22:56
|
show 1 more comment
1
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
1
The issue comes from comparingfloat
withdouble
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use0.1f
for example.
– alamit
Nov 24 '18 at 22:49
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").
– hyde
Nov 24 '18 at 22:56
1
1
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
It's not about precision of float. 0.1 can't be accurately represented with binary "decimal", same way 1/3 can not be represented with base 10 decimals (it becomes 0.33...). Using double will only seem to help, but doesn't for real.
– hyde
Nov 24 '18 at 22:39
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
@hyde So why does it work with double? I know ranged comparison < > is recommended for floating point, but it seems like an overkill for this exercise. I compiled and ran the code with double and it passes the if condition. Do you know why?
– Lev M.
Nov 24 '18 at 22:46
1
1
The issue comes from comparing
float
with double
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use 0.1f
for example.– alamit
Nov 24 '18 at 22:49
The issue comes from comparing
float
with double
, which doesn't have the same precision, and therefore won't store the same result for a repeating binary number such as 0.1. To compare with a float literal OP should use 0.1f
for example.– alamit
Nov 24 '18 at 22:49
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
@alamit thanks, I forgot C defaults to double for decimal literals.
– Lev M.
Nov 24 '18 at 22:54
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to
1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").– hyde
Nov 24 '18 at 22:56
If you have matching types (either both float or both double), then 0.1 parsed as that will equal 0.1 parsed as that. But it won't be equal to 0.1 decimal, ever (because neither float or double has a bit pattern which would be 0.1 decimal). You can change the equality comparison to use float by comparing to
1.0f
, if you don't want to change the variable type to double, and it would "work" again (for suitably defined values of "work").– hyde
Nov 24 '18 at 22:56
|
show 1 more comment
When making comparisons with floating point numbers, one must be careful. Floating point representation of 0.1
is different between 32 bits and 64 bits(float
vs double
). You have defined x to be float
which is compared with 0.1(which is double
). So the comparison will not work correctly. Either you must define x as double
and change nothing else in your code or, make x == 0.1
to x == 0.1f
Further information about this topic can be found this answer and this topic
add a comment |
When making comparisons with floating point numbers, one must be careful. Floating point representation of 0.1
is different between 32 bits and 64 bits(float
vs double
). You have defined x to be float
which is compared with 0.1(which is double
). So the comparison will not work correctly. Either you must define x as double
and change nothing else in your code or, make x == 0.1
to x == 0.1f
Further information about this topic can be found this answer and this topic
add a comment |
When making comparisons with floating point numbers, one must be careful. Floating point representation of 0.1
is different between 32 bits and 64 bits(float
vs double
). You have defined x to be float
which is compared with 0.1(which is double
). So the comparison will not work correctly. Either you must define x as double
and change nothing else in your code or, make x == 0.1
to x == 0.1f
Further information about this topic can be found this answer and this topic
When making comparisons with floating point numbers, one must be careful. Floating point representation of 0.1
is different between 32 bits and 64 bits(float
vs double
). You have defined x to be float
which is compared with 0.1(which is double
). So the comparison will not work correctly. Either you must define x as double
and change nothing else in your code or, make x == 0.1
to x == 0.1f
Further information about this topic can be found this answer and this topic
answered Nov 24 '18 at 23:07
Talip Tolga SarıTalip Tolga Sarı
836
836
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462772%2fscript-in-c-is-not-adding-floats-correctly%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
You should check the return value of scanf, expecially if you want to "end it with ctrl+d".
– Bob__
Nov 24 '18 at 22:17
I wanted to point out the same as @Bob__ did cplusplus.com/reference/cstdio/scanf the scanf function can fail and you do not consider it.
– petrch
Nov 24 '18 at 22:18
2
You would be better off keeping the money in pennies rather than using floating point for fractions.
– Retired Ninja
Nov 24 '18 at 22:38
Yeah, It could be said, that never use floating point numbers for money (unless you intentionally want rounding errors to add up to visible amounts...).
– hyde
Nov 24 '18 at 22:40
@hyde: First, there are decimal floating-point formats in both hardware (including Intel and IBM) and software (including Microsoft) that are perfectly fine for doing the kind of currency calculations shown in this question. So the advice never to use floating-point for money is wrong on that count. Second, floating-point formats, whether binary or decimal, are appropriate for working on financial calculations such as stock market option evaluation, properly designed mortgage calculations, or even calculating sales taxes when done correctly.
– Eric Postpischil
Nov 25 '18 at 0:30