You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This kind of code sometimes is wrong, because you forget to cast x to double before the division and you lose precision (note that here the compiler knows that the result of the division will go in a floating point variable):
void main() {
int x = 15;
double y = x / 10;
}
(The cause is that unfortunately in D the integer division uses the same operator as the FP division. In Python there is the / and // operators. In OcaML there are the / and /., in Delphi there are the / and div operators, in Ada the two operands need to be of the same type).
Seasoned C/C++/D programmers watch for the types every time they perform a division, to avoid that trap, and they often use explicit casts in that kind of code (this uses a recently introduce syntax that avoids the use of a cast()):
double y = double(x) / 10;
But less experienced programmers introduce bugs with divisions. Can D help the programmers reduce the frequency of similar bugs?
- - - - - - - - - - - -
A comment by Daniel Murphy:
> Newbies have to realize that integers aren't real numbers eventually.
I have seen that even programmers with some experience once in a while create this bug. Because you have to keep attention to the types of each division usage, and once in a while your attention slips (or perhaps some bugs of this kind are created by successive type changes).
An example of this possible code found in real code:
Search for "GetTransmission()" in this page:
http://www.viva64.com/en/b/0242/
The possible bug:
int SpectralLMM5Interface::GetTransmission(....,
double& transmission)
{
....
int16_t tr = 0;
memcpy(&tr, answer + 1, 2);
tr = ntohs(tr);
transmission = tr/10;
....
}
- - - - - - - - - - - -
Don suggests:
> It is indeed a common floating-point bug.>> I came up with a solution for this a couple of years ago, never> got around to doing a pull request, but it's on the newsgroup> somewhere. It's a little extension to the range propagation> implementation. You add a boolean flag to the range, which> indicates 'a fractional part has been discarded'. This flag gets> set whenever you perform an integer division (or integer> exponentiation with a negative power), and is cleared whenever> there is a cast or a bitwise operation.>> Then, disallow implicit casting from integer to floating point> whenever the fractional bit is set. Catches all these kinds of> bugs, doesn't require any changes to the language.- - - - - - - - - - - -
The text was updated successfully, but these errors were encountered:
> I came up with a solution for this a couple of years ago, never> got around to doing a pull request, but it's on the newsgroup> somewhere.https://forum.dlang.org/post/hg5291$fas$1@digitalmars.com
bearophile_hugs reported this on 2014-03-24T07:14:56Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=12452
CC List
Description
This kind of code sometimes is wrong, because you forget to cast x to double before the division and you lose precision (note that here the compiler knows that the result of the division will go in a floating point variable): void main() { int x = 15; double y = x / 10; } (The cause is that unfortunately in D the integer division uses the same operator as the FP division. In Python there is the / and // operators. In OcaML there are the / and /., in Delphi there are the / and div operators, in Ada the two operands need to be of the same type). Seasoned C/C++/D programmers watch for the types every time they perform a division, to avoid that trap, and they often use explicit casts in that kind of code (this uses a recently introduce syntax that avoids the use of a cast()): double y = double(x) / 10; But less experienced programmers introduce bugs with divisions. Can D help the programmers reduce the frequency of similar bugs? - - - - - - - - - - - - A comment by Daniel Murphy: > Newbies have to realize that integers aren't real numbers eventually. I have seen that even programmers with some experience once in a while create this bug. Because you have to keep attention to the types of each division usage, and once in a while your attention slips (or perhaps some bugs of this kind are created by successive type changes). An example of this possible code found in real code: Search for "GetTransmission()" in this page: http://www.viva64.com/en/b/0242/ The possible bug: int SpectralLMM5Interface::GetTransmission(...., double& transmission) { .... int16_t tr = 0; memcpy(&tr, answer + 1, 2); tr = ntohs(tr); transmission = tr/10; .... } - - - - - - - - - - - - Don suggests: > It is indeed a common floating-point bug. > > I came up with a solution for this a couple of years ago, never > got around to doing a pull request, but it's on the newsgroup > somewhere. It's a little extension to the range propagation > implementation. You add a boolean flag to the range, which > indicates 'a fractional part has been discarded'. This flag gets > set whenever you perform an integer division (or integer > exponentiation with a negative power), and is cleared whenever > there is a cast or a bitwise operation. > > Then, disallow implicit casting from integer to floating point > whenever the fractional bit is set. Catches all these kinds of > bugs, doesn't require any changes to the language. - - - - - - - - - - - -The text was updated successfully, but these errors were encountered: