Opeartion on a variable and constant giving different result in c
up vote
0
down vote
favorite
A simple calculation: 3^20%15.
The answer, according to a calculator, is 6.
The following code generates answer 7.
#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}
If I replace 20
in the printf
statement with the variable i
, it gives -8
as output.
Assuming that the calculator is corrent (or not?), what is the problem in the program?
Thank you.
c output runtime-error pow mod
add a comment |
up vote
0
down vote
favorite
A simple calculation: 3^20%15.
The answer, according to a calculator, is 6.
The following code generates answer 7.
#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}
If I replace 20
in the printf
statement with the variable i
, it gives -8
as output.
Assuming that the calculator is corrent (or not?), what is the problem in the program?
Thank you.
c output runtime-error pow mod
Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15
1
The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
A simple calculation: 3^20%15.
The answer, according to a calculator, is 6.
The following code generates answer 7.
#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}
If I replace 20
in the printf
statement with the variable i
, it gives -8
as output.
Assuming that the calculator is corrent (or not?), what is the problem in the program?
Thank you.
c output runtime-error pow mod
A simple calculation: 3^20%15.
The answer, according to a calculator, is 6.
The following code generates answer 7.
#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}
If I replace 20
in the printf
statement with the variable i
, it gives -8
as output.
Assuming that the calculator is corrent (or not?), what is the problem in the program?
Thank you.
c output runtime-error pow mod
c output runtime-error pow mod
edited Nov 19 at 15:31
DeiDei
6,08053253
6,08053253
asked Nov 19 at 15:10
nachiketa
32
32
Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15
1
The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31
add a comment |
Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15
1
The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31
Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15
Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15
1
1
The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31
The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31
add a comment |
2 Answers
2
active
oldest
votes
up vote
4
down vote
accepted
The result of pow(3,20)
can't fit in an int
on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.
Changing to a larger integer type such as long long
will do the job.
Moreover, pow
works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20)));
I get 3486784401.000000l
which is not a precise integer value.
1
Additionally, note that poor implementations ofpow
may return inaccurate results forpow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion toint
to produce 3486784400 (before final conversion to 32-bit).
– Eric Postpischil
Nov 19 at 15:17
1
Answers to this question should also address why there is a difference betweenpow(3, 20)
andpow(3, i)
, as the question asked.
– Eric Postpischil
Nov 19 at 15:19
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations ofpow
, not in conversion to an integer.
– Eric Postpischil
Nov 19 at 15:22
@EricPostpischil I don't think there is a difference betweenpow(3, 20)
andpow(3, i)
. The problem the OP is seeing comes from the fact thatint
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
– DeiDei
Nov 19 at 15:23
Likely the compiler evaluatedpow(3, 20)
at compile time andpow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
– Eric Postpischil
Nov 19 at 15:59
add a comment |
up vote
1
down vote
What likely happened here is:
- In your C implementation,
int
is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647. - The result of
pow(3, 20)
is 3486784401. (See note 1 below.) - 3486784401 is too large for an
int
, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything. - In
(int) pow(3, 20)
, the conversion toint
may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7. - In
(int) pow(3, i)
, the conversion toint
may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.
In summary:
- Your code overflows, so the C standard does not define the behavior.
- The compiler likely behaves differently for
pow(3, 20)
andpow(3, i)
because it evaluates the former at compile time and the latter at execution time.
Note
- Good implementations of
pow
return exactly 3486784401 forpow(3, 20)
. Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
The result of pow(3,20)
can't fit in an int
on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.
Changing to a larger integer type such as long long
will do the job.
Moreover, pow
works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20)));
I get 3486784401.000000l
which is not a precise integer value.
1
Additionally, note that poor implementations ofpow
may return inaccurate results forpow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion toint
to produce 3486784400 (before final conversion to 32-bit).
– Eric Postpischil
Nov 19 at 15:17
1
Answers to this question should also address why there is a difference betweenpow(3, 20)
andpow(3, i)
, as the question asked.
– Eric Postpischil
Nov 19 at 15:19
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations ofpow
, not in conversion to an integer.
– Eric Postpischil
Nov 19 at 15:22
@EricPostpischil I don't think there is a difference betweenpow(3, 20)
andpow(3, i)
. The problem the OP is seeing comes from the fact thatint
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
– DeiDei
Nov 19 at 15:23
Likely the compiler evaluatedpow(3, 20)
at compile time andpow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
– Eric Postpischil
Nov 19 at 15:59
add a comment |
up vote
4
down vote
accepted
The result of pow(3,20)
can't fit in an int
on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.
Changing to a larger integer type such as long long
will do the job.
Moreover, pow
works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20)));
I get 3486784401.000000l
which is not a precise integer value.
1
Additionally, note that poor implementations ofpow
may return inaccurate results forpow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion toint
to produce 3486784400 (before final conversion to 32-bit).
– Eric Postpischil
Nov 19 at 15:17
1
Answers to this question should also address why there is a difference betweenpow(3, 20)
andpow(3, i)
, as the question asked.
– Eric Postpischil
Nov 19 at 15:19
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations ofpow
, not in conversion to an integer.
– Eric Postpischil
Nov 19 at 15:22
@EricPostpischil I don't think there is a difference betweenpow(3, 20)
andpow(3, i)
. The problem the OP is seeing comes from the fact thatint
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
– DeiDei
Nov 19 at 15:23
Likely the compiler evaluatedpow(3, 20)
at compile time andpow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
– Eric Postpischil
Nov 19 at 15:59
add a comment |
up vote
4
down vote
accepted
up vote
4
down vote
accepted
The result of pow(3,20)
can't fit in an int
on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.
Changing to a larger integer type such as long long
will do the job.
Moreover, pow
works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20)));
I get 3486784401.000000l
which is not a precise integer value.
The result of pow(3,20)
can't fit in an int
on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.
Changing to a larger integer type such as long long
will do the job.
Moreover, pow
works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20)));
I get 3486784401.000000l
which is not a precise integer value.
edited Nov 19 at 15:20
answered Nov 19 at 15:15
DeiDei
6,08053253
6,08053253
1
Additionally, note that poor implementations ofpow
may return inaccurate results forpow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion toint
to produce 3486784400 (before final conversion to 32-bit).
– Eric Postpischil
Nov 19 at 15:17
1
Answers to this question should also address why there is a difference betweenpow(3, 20)
andpow(3, i)
, as the question asked.
– Eric Postpischil
Nov 19 at 15:19
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations ofpow
, not in conversion to an integer.
– Eric Postpischil
Nov 19 at 15:22
@EricPostpischil I don't think there is a difference betweenpow(3, 20)
andpow(3, i)
. The problem the OP is seeing comes from the fact thatint
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
– DeiDei
Nov 19 at 15:23
Likely the compiler evaluatedpow(3, 20)
at compile time andpow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
– Eric Postpischil
Nov 19 at 15:59
add a comment |
1
Additionally, note that poor implementations ofpow
may return inaccurate results forpow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion toint
to produce 3486784400 (before final conversion to 32-bit).
– Eric Postpischil
Nov 19 at 15:17
1
Answers to this question should also address why there is a difference betweenpow(3, 20)
andpow(3, i)
, as the question asked.
– Eric Postpischil
Nov 19 at 15:19
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations ofpow
, not in conversion to an integer.
– Eric Postpischil
Nov 19 at 15:22
@EricPostpischil I don't think there is a difference betweenpow(3, 20)
andpow(3, i)
. The problem the OP is seeing comes from the fact thatint
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
– DeiDei
Nov 19 at 15:23
Likely the compiler evaluatedpow(3, 20)
at compile time andpow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
– Eric Postpischil
Nov 19 at 15:59
1
1
Additionally, note that poor implementations of
pow
may return inaccurate results for pow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int
to produce 3486784400 (before final conversion to 32-bit).– Eric Postpischil
Nov 19 at 15:17
Additionally, note that poor implementations of
pow
may return inaccurate results for pow(3, 20)
. They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int
to produce 3486784400 (before final conversion to 32-bit).– Eric Postpischil
Nov 19 at 15:17
1
1
Answers to this question should also address why there is a difference between
pow(3, 20)
and pow(3, i)
, as the question asked.– Eric Postpischil
Nov 19 at 15:19
Answers to this question should also address why there is a difference between
pow(3, 20)
and pow(3, i)
, as the question asked.– Eric Postpischil
Nov 19 at 15:19
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of
pow
, not in conversion to an integer.– Eric Postpischil
Nov 19 at 15:22
Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of
pow
, not in conversion to an integer.– Eric Postpischil
Nov 19 at 15:22
@EricPostpischil I don't think there is a difference between
pow(3, 20)
and pow(3, i)
. The problem the OP is seeing comes from the fact that int
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.– DeiDei
Nov 19 at 15:23
@EricPostpischil I don't think there is a difference between
pow(3, 20)
and pow(3, i)
. The problem the OP is seeing comes from the fact that int
can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.– DeiDei
Nov 19 at 15:23
Likely the compiler evaluated
pow(3, 20)
at compile time and pow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.– Eric Postpischil
Nov 19 at 15:59
Likely the compiler evaluated
pow(3, 20)
at compile time and pow(3, i)
at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.– Eric Postpischil
Nov 19 at 15:59
add a comment |
up vote
1
down vote
What likely happened here is:
- In your C implementation,
int
is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647. - The result of
pow(3, 20)
is 3486784401. (See note 1 below.) - 3486784401 is too large for an
int
, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything. - In
(int) pow(3, 20)
, the conversion toint
may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7. - In
(int) pow(3, i)
, the conversion toint
may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.
In summary:
- Your code overflows, so the C standard does not define the behavior.
- The compiler likely behaves differently for
pow(3, 20)
andpow(3, i)
because it evaluates the former at compile time and the latter at execution time.
Note
- Good implementations of
pow
return exactly 3486784401 forpow(3, 20)
. Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.
add a comment |
up vote
1
down vote
What likely happened here is:
- In your C implementation,
int
is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647. - The result of
pow(3, 20)
is 3486784401. (See note 1 below.) - 3486784401 is too large for an
int
, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything. - In
(int) pow(3, 20)
, the conversion toint
may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7. - In
(int) pow(3, i)
, the conversion toint
may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.
In summary:
- Your code overflows, so the C standard does not define the behavior.
- The compiler likely behaves differently for
pow(3, 20)
andpow(3, i)
because it evaluates the former at compile time and the latter at execution time.
Note
- Good implementations of
pow
return exactly 3486784401 forpow(3, 20)
. Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.
add a comment |
up vote
1
down vote
up vote
1
down vote
What likely happened here is:
- In your C implementation,
int
is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647. - The result of
pow(3, 20)
is 3486784401. (See note 1 below.) - 3486784401 is too large for an
int
, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything. - In
(int) pow(3, 20)
, the conversion toint
may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7. - In
(int) pow(3, i)
, the conversion toint
may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.
In summary:
- Your code overflows, so the C standard does not define the behavior.
- The compiler likely behaves differently for
pow(3, 20)
andpow(3, i)
because it evaluates the former at compile time and the latter at execution time.
Note
- Good implementations of
pow
return exactly 3486784401 forpow(3, 20)
. Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.
What likely happened here is:
- In your C implementation,
int
is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647. - The result of
pow(3, 20)
is 3486784401. (See note 1 below.) - 3486784401 is too large for an
int
, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything. - In
(int) pow(3, 20)
, the conversion toint
may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7. - In
(int) pow(3, i)
, the conversion toint
may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.
In summary:
- Your code overflows, so the C standard does not define the behavior.
- The compiler likely behaves differently for
pow(3, 20)
andpow(3, i)
because it evaluates the former at compile time and the latter at execution time.
Note
- Good implementations of
pow
return exactly 3486784401 forpow(3, 20)
. Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.
answered Nov 19 at 15:58
Eric Postpischil
69.3k873150
69.3k873150
add a comment |
add a comment |
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%2f53377522%2fopeartion-on-a-variable-and-constant-giving-different-result-in-c%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
Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15
1
The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31