Problemas com Ponto Flutuante no Windows e no Linux

Opa galera,

Hoje de manhã lá no trabalho um amigo meu ficou com a pulga atrás da orelha, ele tinha um código que formatava um “float” genericamente (pra manter o padrão em todo o sistema), nas na própria declaração dos floats ele estava perdendo a precisão (numa máquina Linux) :shock:

Não havia nenhuma operação acontecendo nem nada, simplesmente por declarar o float perdia a precisão. Mexemos um bocado mas não deu em nada. Agora que eu cheguei em casa refiz os testes (em uma máquina Windows) e tudo funcionou normalmente :?

Se alguém souber se esse comportamento é comum ou tiver como testar esse código aí embaixo no Linux só pra confirmar, seria ótimo :smiley:

public class TestFloats extends TestCase {
	
	public void testFloatToString() {
		
		TestCase.assertEquals( "0.12" , TestFloats.floatToString(0.12f) );
		TestCase.assertEquals( "0.123456" , TestFloats.floatToString(0.123456f) );
		TestCase.assertEquals( "0.1234561" , TestFloats.floatToString(0.1234561f) );
		
	}
	
	public static String floatToString( float f) {
		
		return Float.toString(f);
		
	}
	
}

Maurício,

Não é o caso de usar strictfp ?

http://br.geocities.com/vanessasabino/java/scjp-modificadores.htm
http://java.sun.com/developer/JDCTechTips/2001/tt0410.html

ASOBrasil

Tinha tentado hoje de manhã, mas não funcionou :frowning:

A diferença pode ser por conta do modo de fp padrão do windows ser diferente do linux.

Então é normal ele perder a precisão simplesmente na declaração do número?

O que não se deve fazer é achar que “float” tenha mais de 7 dígitos de precisão. Veja o programa abaixo.

/**
 * Saída esperada deste programa:
<pre>
0 --> 0.0
1 --> 0.9
2 --> 0.99
3 --> 0.999
4 --> 0.9999
5 --> 0.99999
6 --> 0.999999
7 --> 0.9999999
8 --> 1.0
9 --> 1.0

0 --> 0.0
1 --> 0.9
2 --> 0.99
3 --> 0.999
4 --> 0.9999
5 --> 0.99999
6 --> 0.999999
7 --> 0.9999999
8 --> 0.99999999
9 --> 0.999999999
10 --> 0.9999999999
11 --> 0.99999999999
12 --> 0.999999999999
13 --> 0.9999999999999
14 --> 0.99999999999999
15 --> 0.999999999999999
16 --> 0.9999999999999999
17 --> 1.0
18 --> 1.0
19 --> 1.0
</pre>
 */
class TesteFloat {
    public static void main(String[] args) {
        // Vamos tentar imprimir 0, 0.9, 0.99 e assim por diante, até chegar a 1.0.
        for (int i = 0; i < 10; ++i) {
            System.out.println (i + " --> "+ Float.parseFloat ("0.9999999999999999999999999999999999999".substring(0, i+2)));
        }
        System.out.println();
        // A mesma coisa com "double"
        for (int i = 0; i < 20; ++i) {
            System.out.println (i + " --> "+ Double.parseDouble ("0.9999999999999999999999999999999999999".substring(0, i+2)));
        }
    }
}