Numpy losing precision when converting long int to float
It seems numpy
is losing precision on numpy.int64 values when converted to float types.
My numpy version is 1.15.4 which seemed to fix this error.
Here is an example:
>>> value = 734625324872288246
>>> value_plus_1 = 734625324872288246 + 1
>>> items = [value, value_plus_1]
>>> value.bit_length()
60
>>> value_plus_1.bit_length()
60
>>> import numpy as np
>>> a = np.array(items, dtype = np.float128) # larger than needed for value
>>> a
array([7.34625325e+17, 7.34625325e+17], dtype=float128)
>>> a.astype(np.int64) # larger than needed for value
array([734625324872288256, 734625324872288256])
>>> np.__version__
'1.15.4'
As you can see, now both values in the array are equivalent, which shows a loss in precision that I am assuming happens on casting to float.
My question is; Is there something I am doing wrong when creating numpy arrays that can be rectified to not lose precision?
python numpy
add a comment |
It seems numpy
is losing precision on numpy.int64 values when converted to float types.
My numpy version is 1.15.4 which seemed to fix this error.
Here is an example:
>>> value = 734625324872288246
>>> value_plus_1 = 734625324872288246 + 1
>>> items = [value, value_plus_1]
>>> value.bit_length()
60
>>> value_plus_1.bit_length()
60
>>> import numpy as np
>>> a = np.array(items, dtype = np.float128) # larger than needed for value
>>> a
array([7.34625325e+17, 7.34625325e+17], dtype=float128)
>>> a.astype(np.int64) # larger than needed for value
array([734625324872288256, 734625324872288256])
>>> np.__version__
'1.15.4'
As you can see, now both values in the array are equivalent, which shows a loss in precision that I am assuming happens on casting to float.
My question is; Is there something I am doing wrong when creating numpy arrays that can be rectified to not lose precision?
python numpy
add a comment |
It seems numpy
is losing precision on numpy.int64 values when converted to float types.
My numpy version is 1.15.4 which seemed to fix this error.
Here is an example:
>>> value = 734625324872288246
>>> value_plus_1 = 734625324872288246 + 1
>>> items = [value, value_plus_1]
>>> value.bit_length()
60
>>> value_plus_1.bit_length()
60
>>> import numpy as np
>>> a = np.array(items, dtype = np.float128) # larger than needed for value
>>> a
array([7.34625325e+17, 7.34625325e+17], dtype=float128)
>>> a.astype(np.int64) # larger than needed for value
array([734625324872288256, 734625324872288256])
>>> np.__version__
'1.15.4'
As you can see, now both values in the array are equivalent, which shows a loss in precision that I am assuming happens on casting to float.
My question is; Is there something I am doing wrong when creating numpy arrays that can be rectified to not lose precision?
python numpy
It seems numpy
is losing precision on numpy.int64 values when converted to float types.
My numpy version is 1.15.4 which seemed to fix this error.
Here is an example:
>>> value = 734625324872288246
>>> value_plus_1 = 734625324872288246 + 1
>>> items = [value, value_plus_1]
>>> value.bit_length()
60
>>> value_plus_1.bit_length()
60
>>> import numpy as np
>>> a = np.array(items, dtype = np.float128) # larger than needed for value
>>> a
array([7.34625325e+17, 7.34625325e+17], dtype=float128)
>>> a.astype(np.int64) # larger than needed for value
array([734625324872288256, 734625324872288256])
>>> np.__version__
'1.15.4'
As you can see, now both values in the array are equivalent, which shows a loss in precision that I am assuming happens on casting to float.
My question is; Is there something I am doing wrong when creating numpy arrays that can be rectified to not lose precision?
python numpy
python numpy
asked Nov 14 '18 at 13:24
Nathan McCoyNathan McCoy
1,1421126
1,1421126
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
(The question is almost certainly a duplicate, but my search-fu is weak today.)
There are only finitely many numbers that can be represented with 64 bit floating point numbers. The spacing between the numbers that are exactly representable depends on the magnitude of the numbers; you can find the spacing with the function numpy.spacing(x)
for a floating point number x
. In your case, the spacing of the floating point numbers around 734625324872288246 is 128:
In [33]: x = float(734625324872288246)
In [34]: x
Out[34]: 7.346253248722883e+17
In [35]: np.spacing(x)
Out[35]: 128.0
The integer value 734625324872288246 is not representable exactly as floating point. You can see that by casting the float back to integer; you don't get the same value:
In [36]: int(x)
Out[36]: 734625324872288256
You can represent 734625324872288256 exactly as a floating point number, but the next lower representable integer is 734625324872288256 - 128 = 734625324872288128.
And here are the obligatory links for questions about floating point:
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- What Every Programmer Should Know About Floating-Point Arithmetic
add a comment |
The numpy documentation (https://docs.scipy.org/doc/numpy-1.15.0/user/basics.types.html) states that the implementation of float64 only uses 52 bits for the mantissa, and 11 bits for the exponent. This is most likely not enough accuracy to store your 60-bit numbers with full precision.
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%2f53301292%2fnumpy-losing-precision-when-converting-long-int-to-float%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
(The question is almost certainly a duplicate, but my search-fu is weak today.)
There are only finitely many numbers that can be represented with 64 bit floating point numbers. The spacing between the numbers that are exactly representable depends on the magnitude of the numbers; you can find the spacing with the function numpy.spacing(x)
for a floating point number x
. In your case, the spacing of the floating point numbers around 734625324872288246 is 128:
In [33]: x = float(734625324872288246)
In [34]: x
Out[34]: 7.346253248722883e+17
In [35]: np.spacing(x)
Out[35]: 128.0
The integer value 734625324872288246 is not representable exactly as floating point. You can see that by casting the float back to integer; you don't get the same value:
In [36]: int(x)
Out[36]: 734625324872288256
You can represent 734625324872288256 exactly as a floating point number, but the next lower representable integer is 734625324872288256 - 128 = 734625324872288128.
And here are the obligatory links for questions about floating point:
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- What Every Programmer Should Know About Floating-Point Arithmetic
add a comment |
(The question is almost certainly a duplicate, but my search-fu is weak today.)
There are only finitely many numbers that can be represented with 64 bit floating point numbers. The spacing between the numbers that are exactly representable depends on the magnitude of the numbers; you can find the spacing with the function numpy.spacing(x)
for a floating point number x
. In your case, the spacing of the floating point numbers around 734625324872288246 is 128:
In [33]: x = float(734625324872288246)
In [34]: x
Out[34]: 7.346253248722883e+17
In [35]: np.spacing(x)
Out[35]: 128.0
The integer value 734625324872288246 is not representable exactly as floating point. You can see that by casting the float back to integer; you don't get the same value:
In [36]: int(x)
Out[36]: 734625324872288256
You can represent 734625324872288256 exactly as a floating point number, but the next lower representable integer is 734625324872288256 - 128 = 734625324872288128.
And here are the obligatory links for questions about floating point:
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- What Every Programmer Should Know About Floating-Point Arithmetic
add a comment |
(The question is almost certainly a duplicate, but my search-fu is weak today.)
There are only finitely many numbers that can be represented with 64 bit floating point numbers. The spacing between the numbers that are exactly representable depends on the magnitude of the numbers; you can find the spacing with the function numpy.spacing(x)
for a floating point number x
. In your case, the spacing of the floating point numbers around 734625324872288246 is 128:
In [33]: x = float(734625324872288246)
In [34]: x
Out[34]: 7.346253248722883e+17
In [35]: np.spacing(x)
Out[35]: 128.0
The integer value 734625324872288246 is not representable exactly as floating point. You can see that by casting the float back to integer; you don't get the same value:
In [36]: int(x)
Out[36]: 734625324872288256
You can represent 734625324872288256 exactly as a floating point number, but the next lower representable integer is 734625324872288256 - 128 = 734625324872288128.
And here are the obligatory links for questions about floating point:
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- What Every Programmer Should Know About Floating-Point Arithmetic
(The question is almost certainly a duplicate, but my search-fu is weak today.)
There are only finitely many numbers that can be represented with 64 bit floating point numbers. The spacing between the numbers that are exactly representable depends on the magnitude of the numbers; you can find the spacing with the function numpy.spacing(x)
for a floating point number x
. In your case, the spacing of the floating point numbers around 734625324872288246 is 128:
In [33]: x = float(734625324872288246)
In [34]: x
Out[34]: 7.346253248722883e+17
In [35]: np.spacing(x)
Out[35]: 128.0
The integer value 734625324872288246 is not representable exactly as floating point. You can see that by casting the float back to integer; you don't get the same value:
In [36]: int(x)
Out[36]: 734625324872288256
You can represent 734625324872288256 exactly as a floating point number, but the next lower representable integer is 734625324872288256 - 128 = 734625324872288128.
And here are the obligatory links for questions about floating point:
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- What Every Programmer Should Know About Floating-Point Arithmetic
edited Nov 14 '18 at 13:55
answered Nov 14 '18 at 13:45
Warren WeckesserWarren Weckesser
68.4k798132
68.4k798132
add a comment |
add a comment |
The numpy documentation (https://docs.scipy.org/doc/numpy-1.15.0/user/basics.types.html) states that the implementation of float64 only uses 52 bits for the mantissa, and 11 bits for the exponent. This is most likely not enough accuracy to store your 60-bit numbers with full precision.
add a comment |
The numpy documentation (https://docs.scipy.org/doc/numpy-1.15.0/user/basics.types.html) states that the implementation of float64 only uses 52 bits for the mantissa, and 11 bits for the exponent. This is most likely not enough accuracy to store your 60-bit numbers with full precision.
add a comment |
The numpy documentation (https://docs.scipy.org/doc/numpy-1.15.0/user/basics.types.html) states that the implementation of float64 only uses 52 bits for the mantissa, and 11 bits for the exponent. This is most likely not enough accuracy to store your 60-bit numbers with full precision.
The numpy documentation (https://docs.scipy.org/doc/numpy-1.15.0/user/basics.types.html) states that the implementation of float64 only uses 52 bits for the mantissa, and 11 bits for the exponent. This is most likely not enough accuracy to store your 60-bit numbers with full precision.
answered Nov 14 '18 at 13:44
DatHydroGuyDatHydroGuy
6662313
6662313
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%2f53301292%2fnumpy-losing-precision-when-converting-long-int-to-float%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