How to force a Float to only have four decimal places - java-me

How can I make that a float number only have 4 decimal places at most.
In my J2ME app I have two fields : unitPrice (4 decimal places) and quantity(3 decimal places) and when I multiply them I got number with more decimals than I need:
unitPrice :5.6538
quantity: 5
result: 28.269001
What can I do to have a result of only 4 decimals? and in general what do I need to do to use floats with a specific number of decimals.

Of course, if you were using Java SE the solution would be BigDecimal.
You could round as shown in the result initialization in the following program:
import java.math.BigDecimal;
public class Test {
public static void main(String args[]) {
float unitPrice = 5.6538f;
float quantity = 5;
float rawResult = quantity*unitPrice;
System.out.println(rawResult);
float result = Math.round(10000f*rawResult)/10000f;
System.out.println(result);
System.out.println(new BigDecimal(result));
}
}
The output is:
28.269001
28.269
28.2689990997314453125
Unfortunately, as shown by the final printout using BigDecimal, result is not really exactly 28.269. 28.269 is not exactly representable in any binary fraction format. That could affect future calculations if decimal fractions are really important.
As an alternative, consider doing everything in integers, with each type of data having an associated power-of-ten factor. For unit price, the factor would be 10,000. For quantity, it would be 1000.
For the product, you want it to be 10,000. The intermediate result of doing the multiplication will have a factor of 10^7, so divide by 1000 and round to an integer.

in vb6.0 we can use RonudOff() function for this operation;
example:
unitPrice :5.6538
quantity: 5
result: 28.269001
then " RounOff(result)" will give 28.2690;
i think their may be some similar function in java also
thanks

Related

Groovy: How to define float numbers that would generate output as 2 digit decimal points

Algo is to generate random numbers but in form of 2 decimal points like 4.78, 3.88, etc
How can we achieve this?
You can round a float value using DecimalFormat class like:
new java.text.DecimalFormat('#.##').format(yourFloat)
Demo:
Check out Apache Groovy - Why and How You Should Use It article for more information on using Groovy scripting in JMeter
If you return a BigDecimal, you can tell it how many digits it handles. E.g.:
println(new BigDecimal(0.666).setScale(2, java.math.RoundingMode.HALF_UP))
// => 0.67
Only do this at the very end of your calculations.

Groovy - confusion double vs float

I'm using below two statements :-
double foo = 20.00
float bar = 20.00
println foo == bar
And
double foo = 20.01
float bar = 20.01
println foo == bar
It gives the output as :-
true
false
Can anyone know what makes difference between these two statements?
double and float values don't have an exact internal representation for every value. The only decimal values that can be represented as an IEEE-754 binary floating-point for two decimal points are 0, 0.25, 0.5, 0.75 and 1. The rest of representations will always be slightly off, with small differences between doubles and floats creating this inequality behaviour.
This is not just valid for Groovy, but for Java as well.
For example:
double foo = 20.25
float bar = 20.25
println foo == bar
Output:
true
The 0.1 part of 20.01 is infinite repeating in binary; 20.01 =
10100.00000010100011110101110000101000111101011100001010001111010111...
floats are rounded (to nearest) to 24 significant bits; doubles are rounded to 53. That makes the float
10100.0000001010001111011
and the double
10100.000000101000111101011100001010001111010111000011
In decimal, those are
20.0100002288818359375 and
20.010000000000001563194018672220408916473388671875, respectively.
(You could see this directly using my decimal to floating-point converter.)
The Groovy Float aren't kept in the memory precisely. That is the main cause for the differences you have.
In Groovy the definition of the precision by the number of digits after the right side of the dot can be achieved by the following method signature:
public float trunc(int precision)
precision - the number of decimal places to keep.
For more details please follow the Class Float documentation.
It is more prefered to use BigDecimal class as a floating number when using the Groovy language.
The conversion from Number to String is much easier and there is the option to define the precision of the floating number **in the constructor.
BigDecimal(BigInteger unscaledVal, int scale)
Translates a BigInteger unscaled value and an int scale into a BigDecimal.
For more details please follow the Java BigDecimal documentation. As the Groovy language is based on the Java language. More over the BigDecimal will represent the exact value of the number.

default scale of bigdecimal in groovy

What is the default scale of BigDecimal in groovy? And Rounding?
So when trying to do calculations:
def x = 10.0/30.0 //0.3333333333
def y = 20.0/30.0 //0.6666666667
Base on this, I can assume that it uses scale 10 and rounding half up.
Having trouble finding an official documentation saying that though.
You can find it in the official documentation: The case of the division operator
5.5.1. The case of the division operator
The division operators / (and /= for division and assignment) produce
a double result if either operand is a float or double, and a
BigDecimal result otherwise (when both operands are any combination of
an integral type short, char, byte, int, long, BigInteger or
BigDecimal).
BigDecimal division is performed with the divide() method if the
division is exact (i.e. yielding a result that can be represented
within the bounds of the same precision and scale), or using a
MathContext with a precision of the maximum of the two operands'
precision plus an extra precision of 10, and a scale of the maximum of
10 and the maximum of the operands' scale.
And check it in BigDecimalMath.java:
public Number divideImpl(Number left, Number right) {
BigDecimal bigLeft = toBigDecimal(left);
BigDecimal bigRight = toBigDecimal(right);
try {
return bigLeft.divide(bigRight);
} catch (ArithmeticException e) {
// set a DEFAULT precision if otherwise non-terminating
int precision = Math.max(bigLeft.precision(), bigRight.precision()) + DIVISION_EXTRA_PRECISION;
BigDecimal result = bigLeft.divide(bigRight, new MathContext(precision));
int scale = Math.max(Math.max(bigLeft.scale(), bigRight.scale()), DIVISION_MIN_SCALE);
if (result.scale() > scale) result = result.setScale(scale, BigDecimal.ROUND_HALF_UP);
return result;
}
}

Convert UInt32 to float without rounding?

I need to convert a UInt32 type to a float without having it rounded. Say I do
float num = 4278190335;
uint num1 = num;
The value instantly gets changed to 4278190336. Is there any way around this?
I need to convert a UInt32 type to a float without having it rounded.
That can't be done.
There are 232 possible uint values. There are fewer than 232 float values (there are 232 bit patterns, but that includes various NaN values). Add to that the fact that there are obviously a lot of float values which can't be represented as uint (e.g. 0.5) and it becomes clear that you can't represent every uint value exactly in a float. However, every uint (and every int) can be represented exactly as a double, so that might be a solution to your problem.
The problem you're seeing in your original source code is that 4278190335 isn't exactly representable as a float; the closest float value is 4278190336. This isn't a problem with the conversion from float to uint - it's a problem with the conversion from the exact value you've specified in your source code into a float; the float to uint conversion happens separately (and again, can easily lose information).
float has only 23 bits of mantissa. Along with the implicit 1 bit it can only represent exactly all numbers that fit in 24 bits. For numbers larger than that it can only store the nearest value. 4278190335 = 0xFF0000FF > 224 so it'll be rounded to 4278190336 when converting to float
Similarly double has 52 bits of mantissa and can represent all numbers within the range [-253, 253] exactly, so it can store any value that fit in 32-bit int including 4278190335. But again double can't store all numbers in long's range although they have the same size (64 bits)
Aside from your question being worded backward; I think what you are saying is.
You need to get the integer portion of a float value, e.g. its whole number value not its decimal value. In which case you can simply cast the float to an int, casting does not round.
e.g.
float myFloat = 1.5;
uint myInt = (uint)myFloat; //myInt == 1
Keep in mind though this isn't always clear to others reading your code. To help there Math.Floor and Math.Ceiling ... Floor returns the whole number below the current value, ceiling returns the whole number above it
e.g
float myFloat = 1.5;
uint myFloorInt = (uint)Math.Floor(myFloat); //myFloorInt == 1
uint myCeilingInt = (uint)Math.Ceiling(myFloat); //myCeilingInt == 2
You will need to cast or convert the value from float to uint, int, etc. as your needs dictate. Most frown on casting as the resulting value isn't always clear to people ... Convert has various methods to help you convert one value to another in nice clearly understandable way.
There is no solution to turn back the original value in your method.
i suggest to try byte to byte copying to make it posible retrieving data back. float typecasting could change original value.
if your processor is 32bit it could help u:
uint32 x;
float y;
memcpy((uint8*)&y,(uint8*)&x,4);
(mohandes...)

Microsoft.DirectX.Vector3.Normalize() inconsistency

Two ways to normalize a Vector3 object; by calling Vector3.Normalize() and the other by normalizing from scratch:
class Tester {
static Vector3 NormalizeVector(Vector3 v)
{
float l = v.Length();
return new Vector3(v.X / l, v.Y / l, v.Z / l);
}
public static void Main(string[] args)
{
Vector3 v = new Vector3(0.0f, 0.0f, 7.0f);
Vector3 v2 = NormalizeVector(v);
Debug.WriteLine(v2.ToString());
v.Normalize();
Debug.WriteLine(v.ToString());
}
}
The code above produces this:
X: 0
Y: 0
Z: 1
X: 0
Y: 0
Z: 0.9999999
Why?
(Bonus points: Why Me?)
Look how they implemented it (e.g. in asm).
Maybe they wanted to be faster and produced something like:
l = 1 / v.length();
return new Vector3(v.X * l, v.Y * l, v.Z * l);
to trade 2 divisions against 3 multiplications (because they thought mults were faster than divs (which is for modern fpus most often not valid)). This introduced one level more of operation, so the less precision.
This would be the often cited "premature optimization".
Don't care about this. There's always some error involved when using floats. If you're curious, try changing to double and see if this still happens.
You should expect this when using floats, the basic reason being that the computer processes in binary and this doesn't map exactly to decimal.
For an intuitive example of issues between different bases consider the fraction 1/3. It cannot be represented exactly in Decimal (it's 0.333333.....) but can be in Terniary (as 0.1).
Generally these issues are a lot less obvious with doubles, at the expense of computing costs (double the number of bits to manipulate). However in view of the fact that a float level of precision was enough to get man to the moon then you really shouldn't obsess :-)
These issues are sort of computer theory 101 (as opposed to programming 101 - which you're obviously well beyond), and if your heading towards Direct X code where similar things can come up regularly I'd suggest it might be a good idea to pick up a basic computer theory book and read it quickly.
You have here an interesting discussion about String formatting of floats.
Just for reference:
Your number requires 24 bits to be represented, which means that you are using up the whole mantissa of a float (23bits + 1 implied bit).
Single.ToString () is ultimately implemented by a native function, so I cannot tell for sure what is going on, but my guess is that it uses the last digit to round the whole mantissa.
The reason behind this could be that you often get numbers that cannot be represented exactly in binary, so you would get a long mantissa; for instance, 0.01 is represented internally as 0.00999... as you can see by writing:
float f = 0.01f;
Console.WriteLine ("{0:G}", f);
Console.WriteLine ("{0:G}", (double) f);
by rounding at the seventh digit, you will get back "0.01", which is what you would have expected.
For what seen above, numbers with only 7 digits will not show this problem, as you already saw.
Just to be clear: the rounding is taking place only when you convert your number to a string: your calculations, if any, will use all the available bits.
Floats have a precision of 7 digits externally (9 internally), so if you go above that then rounding (with potential quirks) is automatic.
If you drop the float down to 7 digits (for instance, 1 to the left, 6 to the right) then it will work out and the string conversion will as well.
As for the bonus points:
Why you ? Because this code was 'eager to blow on you'.
(Vulcan... blow... ok.
Lamest.
Punt.
Ever)
If your code is broken by minute floating point rounding errors, then I'm afraid you need to fix it, as they're just a fact of life.

Resources