Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert float to double while preserving decimal point precision?

I have a float-based storage of decimal by their nature numbers. The precision of float is fine for my needs. Now I want to perform some more precise calculations with these numbers using double.

An example:

float f = 0.1f;
double d = f; //d = 0.10000000149011612d
// but I want some code that will convert 0.1f to 0.1d;

I know very well that 0.1f != 0.1d. This question is not about precise decimal calculations. In other words...

Let's say I work with an API that returns float numbers for decimal MSFT stock prices. Believe or not, this API exists:

interface Stock {
    float[] getDayPrices();
    int[] getDayVolumesInHundreds();
}

It is known that the price of a MSFT share is a decimal number with no more than 5 digits, e.g. 31.455, 50.12, 45.888. Obviously the API does not work with BigDecimal because it would be a big overhead for the purpose to just pass the price.

Let's also say I want to calculate a weighted average of these prices with double precision:

float[] prices = msft.getDayPrices();
int[] volumes = msft.getDayVolumesInHundreds();
double priceVolumeSum = 0.0;
long volumeSum = 0;
for (int i = 0; i < prices.length; i++) {
    double doublePrice = decimalFloatToDouble(prices[i]);
    priceVolumeSum += doublePrice * volumes[i];
    volumeSum += volumes[i];
}
System.out.println(priceVolumeSum / volumeSum);

I need a performant implemetation of decimalFloatToDouble.

Now I use the following code, but I need something more clever:

double decimalFloatToDouble(float f) {
    return Double.parseDouble(Float.toString(f));
}
like image 427
Yahor Avatar asked Sep 19 '25 01:09

Yahor


1 Answers

EDIT: this answer corresponds to the question as initially phrased.

When you convert 0.1f to double, you obtain the same number, the imprecise representation of the rational 1/10 (which cannot be represented in binary at any precision) in single-precision. The only thing that changes is the behavior of the printing function. The digits that you see, 0.10000000149011612, were already there in the float variable f. They simply were not printed because these digits aren't printed when printing a float.

Ignore these digits and compute with double as you wish. The problem is not in the conversion, it is in the printing function.

like image 181
Pascal Cuoq Avatar answered Sep 20 '25 15:09

Pascal Cuoq