I'm creating an RPN calculator for a school project and having trouble with the modulus operator. Since we're using the double data type, modulus won't work on floating-point numbers. For example, 0.5 % 0.3 should return 0.2, but I'm getting a division by zero exception.
The instruction says to use fmod(). I've looked everywhere for fmod(), including javadoc, but I can't find it. I'm starting to think it's a method I'm going to have to create?
Edit: Hmmm, strange. I just plugged in those numbers again and it seems to be working fine… but just in case. Do I need to watch out for using the mod operator in Java when using floating types? I know something like this can't be done in C++ (I think).
You probably had a typo when you first ran it.
evaluating 0.5 % 0.3 returns '0.2' (A double) as expected.
Mindprod has a good overview of how modulus works in Java.
Unlike C, Java allows using the % for both integer and floating point and (unlike C89 and C++) it is well-defined for all inputs (including negatives):
From JLS §15.17.3:
The result of a floating-point
remainder operation is determined by
the rules of IEEE arithmetic:
If either operand is NaN, the result is NaN.
If the result is not NaN, the sign of the result equals the sign of
the dividend.
If the dividend is an infinity, or the divisor is a zero, or both, the
result is NaN.
If the dividend is finite and the divisor is an infinity, the result
equals the dividend.
If the dividend is a zero and the divisor is finite, the result
equals the dividend.
In the remaining cases, where neither an infinity, nor a zero, nor
NaN is involved, the floating-point
remainder r from the division of a
dividend n by a divisor d is defined
by the mathematical relation r=n-(d·q)
where q is an integer that is negative
only if n/d is negative and positive
only if n/d is positive, and whose
magnitude is as large as possible
without exceeding the magnitude of the
true mathematical quotient of n and d.
So for your example, 0.5/0.3 = 1.6... . q has the same sign (positive) as 0.5 (the dividend), and the magnitude is 1 (integer with largest magnitude not exceeding magnitude of 1.6...), and r = 0.5 - (0.3 * 1) = 0.2
I thought the regular modulus operator would work for this in Java, but it can't be hard to code. Just divide the numerator by the denominator, and take the integer portion of the result. Multiply that by the denominator, and subtract the result from the numerator.
x = n/d
xint = Integer portion of x
result = n - d*xint
fmod is the standard C function for handling floating-point modulus; I imagine your source was saying that Java handles floating-point modulus the same as C's fmod function. In Java you can use the % operator on doubles the same as on integers:
int x = 5 % 3; // x = 2
double y = .5 % .3; // y = .2
Related
For example,
int result;
result = 125/100;
or
result = 43/100;
Will result always be the floor of the division? What is the defined behavior?
Will result always be the floor of the division? What is the defined behavior?
Not quite. It rounds toward 0, rather than flooring.
6.5.5 Multiplicative operators
6 When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.88) If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
and the corresponding footnote:
This is often called ‘‘truncation toward zero’’.
Of course two points to note are:
3 The usual arithmetic conversions are performed on the operands.
and:
5 The result of the / operator is the
quotient from the division of the
first operand by the second; the
result of the % operator is the
remainder. In both operations, if the
value of the second operand is zero,
the behavior is undefined.
[Note: Emphasis mine]
Dirkgently gives an excellent description of integer division in C99, but you should also know that in C89 integer division with a negative operand has an implementation-defined direction.
From the ANSI C draft (3.3.5):
If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.
So watch out with negative numbers when you are stuck with a C89 compiler.
It's a fun fact that C99 chose truncation towards zero because that was how FORTRAN did it. See this message on comp.std.c.
Yes, the result is always truncated towards zero. It will round towards the smallest absolute value.
-5 / 2 = -2
5 / 2 = 2
For unsigned and non-negative signed values, this is the same as floor (rounding towards -Infinity).
Where the result is negative, C truncates towards 0 rather than flooring - I learnt this reading about why Python integer division always floors here: Why Python's Integer Division Floors
Will result always be the floor of the division?
No. The result varies, but variation happens only for negative values.
What is the defined behavior?
To make it clear floor rounds towards negative infinity,while integer division rounds towards zero (truncates)
For positive values they are the same
int integerDivisionResultPositive= 125/100;//= 1
double flooringResultPositive= floor(125.0/100.0);//=1.0
For negative value this is different
int integerDivisionResultNegative= -125/100;//=-1
double flooringResultNegative= floor(-125.0/100.0);//=-2.0
I know people have answered your question but in layman terms:
5 / 2 = 2 //since both 5 and 2 are integers and integers division always truncates decimals
5.0 / 2 or 5 / 2.0 or 5.0 /2.0 = 2.5 //here either 5 or 2 or both has decimal hence the quotient you will get will be in decimal.
I want to create a setter for a double variable num, but I would only like to update it if the input is a multiple of 0.5.
Here's what I have, but I'm worried about floating-point errors.
public void setNum(double num) {
if (num % 0.5 == 0.0) {
this.num = num;
}
}
I assume that for some inputs that actually are a multiple of 0.5, it might return some 0.0000003 or 0.49999997, thus not 0.0.
What can I do to remedy this? Or is this not a problem in this case?
Unless you're dealing with really big floating point numbers, you won't lose accuracy for something that actually is an exact multiple of 0.5, because 0.5 is exactly expressible in binary. But for a number that is close enough to a multiple of 0.5, you might find that (e.g.) 10.500000000000000001 has been stored as 10.5.
So (num % 0.5 == 0.0) will definitely be true if num is a multiple of 0.5, but it might also be true if num is a slightly inaccurate representation of a number that is close to a multiple of 0.5.
Java’s % operator never introduces any rounding error because the result is always small enough that it is able to represent the exact remainder.
The Java Language Specification, Java SE 11 Edition, 15.7.3 defines % for cases not involving NaNs, infinities, or zeros:
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from the division of a dividend n by a divisor d is defined by the mathematical relation r = n - (d ⋅ q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.
Thus the magnitude of r is not greater than the magnitude of n (because we subtract some d ⋅ q from n that is smaller than n in magnitude and that is zero or has the same sign as n) and is less than the magnitude of d (because otherwise q could be one larger in magnitude). This means r is at least as fine as n and q—its exponent is at least as small as n’s exponent and as q’s exponent. And that means no significant bits in the binary representation of n - (d ⋅ q) are below the position value of r’s lowest bit. Therefore, no significant bits were beyond the point where r had to be rounded. So nothing was lost in rounding. So r is an exact result.
Can result ever be false because 4 / 2.0 may return something like 1.99999999? More generally than the title:
int a = // any valid int
int b = // any valid int
boolean result = (a/(double)b) >= a/b;
If this is possible, can anyone provide an example of a and b? If this isn't possible, is there any java or floating point specification which proves this?
I wrote this logic a few minutes ago, and suddenly worried about it breaking. I have been unable to break it, but I'm wondering if it's guaranteed across all JVMs.
If a and b are positive int values, then a/(double)b >= a/b.
I use the following premises, along with understood semantics, such as that the int value of a/b will be converted to double for the comparison with the other operand of >=.
Premises:
The range of int is [-2,147,483,648, 2,147,483,648).
double is IEEE 754 64-bit binary.
The rounding mode is round-to-nearest.
All floating-point operations, particularly division, conform to IEEE 754.
The integer a/b truncates toward zero.
Notation:
a is the mathematical value of a.
b is the mathematical value of b.
Mathematical expressions, such as a/b, are exact, as distinct from computed expressions such as a/b.
Let L be the value produced for a/(double)b.
Let R be the value produced for a/b.
Proof:
All int values are representable in double, so IEEE 754 requires that converting int to double be exact.
Therefore, (double) a and (double) b produce a and b exactly, and a/(double)b produces a/b correctly rounded to the nearest double.
Since R is a/b truncated toward zero, and a/b is positive, R is floor(a/b).
The greatest a/b can be is 2,147,483,647/1 = 2,147,483,647. Each integer at this magnitude and below is exactly representable as a double.
L is the double nearest a/b. If L is reduced by rounding, it is reduced to the next lower double. Since all integers at this magnitude are representable, floor(a/b) is representable, so L is at least floor(a/b).
Therefore L ≥ R.
The conversion of R to double is exact, so the comparison of L to R with >= produces the same result as the mathematical L ≥ R.
For negative numbers, it fails for a = -10, b = 3.
For positive inputs only, I think you are safe.
Let x be the real number result of dividing a by b.
First consider the case where x is representable as an int. It is also representable as a double, and both calculations return x.
Now suppose x is not an int. The question is whether the absolute value of the rounding error difference between x and a/(double b) can ever exceed the truncation error for a/b. It cannot.
The truncation error t = x - a/b must be at least 1/b. x cannot be bigger than Integer.MAX_VALUE/b, so t/x is at least 1/Integer.MAX_VALUE. That is much greater than the maximum rounding error on a correctly rounded double calculation.
4 / 2.0 must return 2.0 because floating-point division is exact.
Negative numbers may cause your comparison to fail, though. Note that -1/2 = 0 while -1.0/2.0 = -0.5.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I turn a floating point number into the closest fraction represented by a byte numerator and denominator?
I would like to take an arbitrary float or double in Java and convert it to a rational number - ie. a number of the form a/b where a and b are long integers. How can I do this in a reasonably efficient way?
(BTW - I already have code for simplifying the fractions, so it doesn't matter whether a/b are in their simplest form).
First see how double (or float but I refer only to double below) is constructed by IEEE-754 rules:
Then convert double to bits with Double.doubleToLongBits.
Count the fraction using this method 1 + bit_0 * 2^(-1) + bit_1 * 2^(-2) ....
Multiply the result with exponent (2^(exponent) to be precise) and with a sign.
Here is the code:
double number = -0.15625;
// Code below doesn't work for 0 and NaN - just check before
long bits = Double.doubleToLongBits(number);
long sign = bits >>> 63;
long exponent = ((bits >>> 52) ^ (sign << 11)) - 1023;
long fraction = bits << 12; // bits are "reversed" but that's not a problem
long a = 1L;
long b = 1L;
for (int i = 63; i >= 12; i--) {
a = a * 2 + ((fraction >>> i) & 1);
b *= 2;
}
if (exponent > 0)
a *= 1 << exponent;
else
b *= 1 << -exponent;
if (sign == 1)
a *= -1;
// Here you have to simplify the fraction
System.out.println(a + "/" + b);
But be careful - with big exponents you may run into numbers that won't fit into your variables. In fact you may consider storing exponent along the fraction and only multiply it if exponent is small enough. If it's not and you have to display the fraction to the user you may use the scientific notation (that requires solving equation 2^n = x * 10^m where m is your decimal exponent and x is a number you have to multiply the fraction with. But that's a matter for another question...).
Let long bits = Double.doubleToLongBits(double). From the Javadoc of Double.longBitsToDouble:
...let s, e, and m be three values that can be computed from the argument:
int s = ((bits >> 63) == 0) ? 1 : -1;
int e = (int)((bits >> 52) & 0x7ffL);
long m = (e == 0) ?
(bits & 0xfffffffffffffL) << 1 :
(bits & 0xfffffffffffffL) | 0x10000000000000L;
Then the floating-point result equals the value of the mathematical expression s·m·2e-1075.
That result is most certainly a rational number.
The rational number corresponding to any FP value is (mantissa/2^-exponent), where the mantissa and exponent are as defined in IEEE 754 (Wiki reference). You can then apply divisions by LCD (or I guess GCF) to get a canonical rational number.
The various concepts contained under the rubric continued fractions yield best-possible rational approximations for a given maximum denominator. Specifically, you're asking about calculating a convergent sequence. At some point, when your denominator is large enough according to whatever criteria you want (or are forced upon you by finite integer implementation lengths), terminate calculating the convergent terms and use the last one. Algorithms are described in rather good detail on the linked Wikipedia pages.
To address one concern you raised, the fractions generated in the convergent sequence are always in reduced form. They are also provably the best possible approximations for a given denominator. Precisely, a convergent term of the form m/n is closer to the target number than another other fraction with denominator < n. In other words, the convergent algorithm yields better approximations than trial and error.
As you know, floating point numbers cannot store even simple numbers such as 0.1 exactly. If you use a naïve approach for converting floating point numbers, then you might end up with huge numerators and denomiators.
However, there are algorithms that might help: the Dragon4 and Grisu3 algorithms are designed to create the most readable output for floating point numbers. They take into advantage that certain floating point bit sequences can be expressed by several decimal fractions and choose the shortest of these.
For a first implementation, I would use Dragon4 and/or Grisu3 to create the shortest decimal fraction out of the floating point. For example the floating point number with the bits cd cc cc cc cc cc f4 3f would result in the decimal fraction 1.3 instead of 1.29999999. I then would express the decimal fraction in the form a/b and simplify it. In the given example, this would be 13/10, with no further simplification.
Please note that the conversion into a decimal fraction may be a disadvantage. For example, the rational number 1/3 cannot be expressed exactly in both decimal and floating point numbers. So, the best solution would be to modify an algorithm such as Dragon4 to use arbitrary fractional denominators and not just 10. Alas, this almost certainly will require quite a lot of work and some CS background.
I had already searched through different questions on this topic but not get a clear idea.
Check this code:
class Test{
public static void main(String[] s){
int a=5;
float b=(float)a/0;
System.out.print(b);
}
}
the output is Infinity. But the thing I'm not getting is a is an int and a/0 must throw an exception. So how can it show output Infinity?
The reason is that
(float)a/0;
is interpreted as
((float)a)/0;
and not
(float)(a/0);
so you actually are converting a to a float before doing the division, not doing an integer division and then converting the result.
Hope this helps!
You are not dividing an integer by zero. You're dividing a float by zero, because your expression is equivalent to:
float b=((float)a)/0;
If you force the division to occur with only integers instead, like in the following example, the expected ArithmeticException will be thrown.
float b=(float)(a/0);
All floating-point computations follow the IEEE 754 specification. In particular, there
are three special floating-point values to denote overflows and errors:
• Positive infinity
• Negative infinity
• NaN (not a number)
For example, the result of dividing a positive number by 0 is positive infinity. Computing
0/0 or the square root of a negative number yields NaN.
see also
CAUTION: Floating-point numbers are not suitable for financial
calculation in which roundoff errors cannot be tolerated. For example,
the command System.out.println(2.0 -
1.1) prints 0.8999999999999999, not 0.9 as you would expect. Such
roundoff errors are caused by the fact that floating-point numbers are
represented in the binary number system. There is no precise binary
representation of the fraction 1/10, just as there is no accurate
representation of the fraction 1/3 in the decimal system. If you need
precise numerical computations without roundoff errors, use the
BigDecimal class, which is introduced later in this chapter.
from core Java Volume 1 chapter 3
a is an int, except you cast it to a float at the time the division occurs. Note that the cast has higher precedence than division - with brackets for clarity it would be:
float b = ((float) a)/0;
So while a is an int, you're doing floating point division.
This is because Java doesn't allow division by zero with ints and it does with floating-point values.
Infinity is produced if a floating point operation creates such a large floating-point number that it cannot be represented normally.
The cast to float of a generates a automatic cast of 0 to float aswell
Because you're casting a to a float, then dividing by zero. Floats have +/- infinity.
http://www.velocityreviews.com/forums/t137207-division-by-zero-float-vs-int.html
The binary / operator performs division, producing the quotient of its operands. The left-hand operand is the dividend and the right-hand operand is the divisor.
Integer division rounds toward 0. That is, the quotient produced for operands n and d that are integers after binary numeric promotion (§5.6.2) is an integer value q whose magnitude is as large as possible while satisfying |d·q||n|; moreover, q is positive when |n||d| and n and d have the same sign, but q is negative when |n||d| and n and d have opposite signs. There is one special case that does not satisfy this rule: if the dividend is the negative integer of largest possible magnitude for its type, and the divisor is -1, then integer overflow occurs and the result is equal to the dividend. Despite the overflow, no exception is thrown in this case. On the other hand, if the value of the divisor in an integer division is 0, then an ArithmeticException is thrown.
The result of a floating-point division is determined by the specification of IEEE arithmetic:
If either operand is NaN, the result is NaN.
If the result is not NaN, the sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
Division of an infinity by an infinity results in NaN.
Division of an infinity by a finite value results in a signed infinity. The sign is determined by the rule stated above.
Division of a finite value by an infinity results in a signed zero. The sign is determined by the rule stated above.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero. The sign is determined by the rule stated above.
Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule stated above.
In the remaining cases, where neither an infinity nor NaN is involved, the exact mathematical quotient is computed. A floating-point value set is then chosen:
If the division expression is FP-strict (§15.4):
If the type of the division expression is float, then the float value set must be chosen.
If the type of the division expression is double, then the double value set must be chosen.
If the division expression is not FP-strict:
If the type of the division expression is float, then either the float value set or the float-extended-exponent value set may be chosen, at the whim of the implementation.
If the type of the division expression is double, then either the double value set or the double-extended-exponent value set may be chosen, at the whim of the implementation.
Next, a value must be chosen from the chosen value set to represent the quotient. If the magnitude of the quotient is too large to represent, we say the operation overflows; the result is then an infinity of appropriate sign. Otherwise, the quotient is rounded to the nearest value in the chosen value set using IEEE 754 round-to-nearest mode. The Java programming language requires support of gradual underflow as defined by IEEE 754 (§4.2.4).
Despite the fact that overflow, underflow, division by zero, or loss of information may occur, evaluation of a floating-point division operator / never throws a run-time exception.
This can be verified at: http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.17.2