[java] -0.0f != 0.0f

Pagina: 1
Acties:

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Ik ben tegen het volgende probleem aangelopen:
-0.0f != 0.0f
Ik snap dat je de 0 dus schijnbaar op 2 manieren kan schrijven, maar ik weet niet hoe ik deze expressie om kan zetten naar een (efficiente) expressie die wel doet wat ik wil.

  • dlmh
  • Registratie: Januari 2000
  • Laatst online: 22-05 08:48

dlmh

Lo-Fi

Het is op zich niet zo raar dat -0.0 anders in Floating point wordt weergegeven dan +0.0f omdat daar een bit voor gereserveerd is binnen dat getal. Als je nou Math.abs(Float f) gebruikt?

“If a cluttered desk is a sign of a cluttered mind, of what, then, is an empty desk a sign?” - Albert Einstein


Verwijderd

(int) Math.round(Float f) ben je mss ook iets mee...

  • whoami
  • Registratie: December 2000
  • Laatst online: 09:01
Mja, floating point is nooit helemaal precies, dus eigenlijk zou met een bepaalde marge moeten rekening houden als je een vergelijking doet; zoiets bv:

code:
1
2
3
4
5
6
7
8
if( (-0.0f) - (+0.0f) <= Math.Abs(0.00001f) )
{
     // gelijk
}
else
{
    // niet gelijk
}

[ Voor 3% gewijzigd door whoami op 29-08-2004 09:46 ]

https://fgheysels.github.io/


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Wil je in je onderbewustzijn misschien liever met decimale getalen werken?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Ik ben er intussen al uit. Ik heb het geluk dat ik een overkoepelend object heb waar die float in terecht komt, en daar kan ik het wat aansturen. Afgezien van de equals, ging de hashcode namelijk ook fout. De hashcode van 0.0f is anders dan -0.0f.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public final class FloatConstant extends Constant{

    private static final long serialVersionUID = 0L;

    public final float _value;
    private final int _hashcode;
    
    public FloatConstant(float value){
        super(FLOAT_CONSTANT);
        _value = value==-0.0f?0.0f:value;
        _hashcode = Float.floatToIntBits(_value);
    }

    public FloatConstant(float value, SourceLoc loc){
        super(FLOAT_CONSTANT,loc);
        _value = value==-0.0f?0.0f:value;
        _hashcode = Float.floatToIntBits(_value);       
    }

    public float getValue(){
        return _value;
    }

    public void accepts(TermVisitor v) {
        v.visit(this);
    }

    public boolean isMatchable(Term t){
        assert t!=null;

        if(t._type==VAR_TERM)
            return true;

        if(t._type!=FLOAT_CONSTANT)
            return false;

        return ((FloatConstant)t)._value==_value;
    }

    public String toString(){
        return Float.toString(_value);
    }

    public boolean equals(Object item){
        if(item == null)
            return false;
        if(item == this)
            return true;
        if(item.hashCode()!=hashCode())
            return false;
        if(!(item instanceof FloatConstant))
            return false;
        FloatConstant otherConstant = (FloatConstant)item;
        return otherConstant._value==_value;
    }

    public int hashCode(){
        return _hashcode; 
    }
}

[ Voor 21% gewijzigd door Alarmnummer op 29-08-2004 11:52 ]


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Dat is natuurlijk een aardige workaround, maar zouden decimale getallen misschien geen betere, volledige oplossing zijn? Ik weet natuurlijk niet wat de precieze toepassing is.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
mbravenboer schreef op 29 augustus 2004 @ 11:48:
Dat is natuurlijk een aardige workaround, maar zouden decimale getallen misschien geen betere, volledige oplossing zijn? Ik weet natuurlijk niet wat de precieze toepassing is.
De FloatConstant heb ik nodig als onderdeel van een Prolog term (expressie) om Prolog met floating point getallen te laten werken. Ik ben hoe dan ook die FloatConstant nodig. En verder geld in prolog dat 0.0=-0.0 dus ik moet me hier ook aan houden (als ik ISO compliant wil zijn)

[ Voor 6% gewijzigd door Alarmnummer op 29-08-2004 11:52 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Vreemd, was Java niet IEEE-754 compliant? Ik weet dat de meest recente Java-versies dat optioneel maken, maar zonder "relaxed math" oid zou IEEE-754 moeten gelden en dan is -0.0==+0.0

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
MSalters: Vreemd, was Java niet IEEE-754 compliant?
Inderdaad, maar alleen als je de strictfp modifier gebruikt. Ik wist niet dat in IEEE-754 geldt dat -0.0==+0.0, maar die modifier moet dan dus het probleem fraaier oplossen.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • jvo
  • Registratie: Augustus 2001
  • Laatst online: 04-10-2023

jvo

geen commentaar

MSalters schreef op 30 augustus 2004 @ 09:03:
Vreemd, was Java niet IEEE-754 compliant? Ik weet dat de meest recente Java-versies dat optioneel maken, maar zonder "relaxed math" oid zou IEEE-754 moeten gelden en dan is -0.0==+0.0
Bij mij lijken ze ook gewoon gelijk te zijn.
System.out.println(0.0 == -0.0); geeft true. Je gebruikt wel float of double en niet Float of Double toch? De door mij gebruikte sdk is overigens 1.4.0 beta 3.
Pagina: 1