2017-01-25 1 views
2

Ich mache ein Spiel, in dem ich einen Ort mit einem Schwimmer setze, ist das Problem, der Schwimmer wird nicht höher sie 255? Dies ist, wie mache ich die Schwimmer höher gehen: 1. add-Methode:Float kann nicht über 256 gehen?

public Location add(float x, float y, float z){ 
    this.x += x; this.y += y; this.z += z; 
    return this; 
} 

2. Update-Methode

public void update(){ 
     float speed = 0.00001f; 
     float rotspeed = 0.00001f; 
     if (Keyboard.isKeyDown(Keyboard.KEY_UP)) Main.renderer.rotate(-rotspeed, 0, 0); 
     if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) Main.renderer.rotate(rotspeed, 0, 0); 
     if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) Main.renderer.rotate(0, rotspeed, 0); 
     if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) Main.renderer.rotate(0, -rotspeed, 0); 

     if (Keyboard.isKeyDown(Keyboard.KEY_W)) Main.renderer.renderLocation.add(0, 0, speed); 
     if (Keyboard.isKeyDown(Keyboard.KEY_S)) Main.renderer.renderLocation.add(0, 0, -speed); 
     if (Keyboard.isKeyDown(Keyboard.KEY_D)) Main.renderer.renderLocation.add(-speed, 0, 0); 
     if (Keyboard.isKeyDown(Keyboard.KEY_A)) Main.renderer.renderLocation.add(speed, 0, 0); 

     if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) Main.renderer.renderLocation.add(0, -speed, 0); 
     if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) Main.renderer.renderLocation.add(0, speed, 0); 
     fixRenderRotation(); 
    } 

Das Update in einer while-Schleife in einem untergeordneten Thread aufgerufen wird . Diese

ist, was ich für

public void update(){ 
    System.out.println("render_location "+renderLocation.x+" "+renderLocation.y+" "+renderLocation.z+" rotation "+rotation.x+" "+rotation.y+" "+rotation.z); 
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); 
    GL11.glLoadIdentity(); 
    GL11.glTranslatef(renderLocation.x, renderLocation.y, renderLocation.z); 
    //GL11.glTranslatef(renderLocation.x, renderLocation.y, renderLocation.z); 
    GL11.glRotatef(rotation.x, 1F, 0F, 0F); 
    GL11.glRotatef(rotation.y, 0F, 1F, 0F); 
    GL11.glRotatef(rotation.z, 0F, 0F, 1F); 
    ((RenderObject.UnknownRenderInformation) collection.getRenderInformation()).act(); 
} 

den Schwimmer mit Es ist die renderLocaiton Variable. Ich halte es nicht davon ab, höher zu gehen.

+1

* Etwas * ist, und das ist nicht die interne Darstellung von Schwimmern. –

+0

@DaveNewton bist du sicher? Ich würde mich fragen, ob ein "float" genau genug war, um "255.00001f" im Unterschied zu "255f" darzustellen. –

+0

@LouisWasserman \t Sicher, aber das ist nicht, was die Frage fragt - OP sagt, es wird nicht über 256 gehen. Oder 255, je nachdem, welchen Satz Sie gelesen haben. –

Antwort

3

float hat nur ~ 6 Stellen der Genauigkeit. Ich schlage vor, ein int mit und Dividieren durch 100.000 oder ein double

Verwendung Wenn Sie 1e-5f zu 256f hinzufügen die Antwort 256f, da dies am nächsten repräsentieren-able Wert ist. Sie haben das gleiche Problem mit Doppel, aber an einem viel höheren Punkt. Wenn Sie 1e-5 zu 137438953472 hinzufügen, wird dasselbe passieren, da Sie über die Präzision eines double hinaus arbeiten.

Wenn Sie ein int verwenden, werden Sie ein anderes Problem haben. In 1-2147483647 und die int überlaufen zu -2147483648

BTW Sie ein Problem mit Schwimmer haben, bevor Sie 256. Aufgrund Darstellungsfehler erreichen 128f + 1e-5f == 128.00002, die ich vermute, ist nicht das, was Sie bestimmt.

In der Tat, wenn Sie weiterhin hinzufügen 1e-5f es dauert nur 65536 mal zu Inkrementieren zwischen Integer-Wert/ganze Zahlen statt der 100.000, die Sie erwartet haben.

Es ist nützlich, die Grenzen Ihrer Typen zu kennen.

1

auf die Antwort der Peter Hinzufügen, ist dies eine Pflichtlese: What every computer scientist should know about floating-point arithmetic

Was im Grunde bekommt ist passiert 256.00001f abgerundet auf 256f (255.00001f, auf der anderen Seite, ist aufzurunden zu 255.00002f). Sie können 256.00002f speichern, es wird jedoch auf 256.00003f aufgerundet. Das erste Runden down passiert bei 256.00001f und das ist, wo Sie das Limit treffen, so dass jede andere 0.00001 Addition keine Wirkung haben wird (jedes Mal, wenn Sie es hinzufügen, wird es wegen der Rundung verworfen). Wie Sie vielleicht bemerkt haben, ist die fünfte Dezimalstelle eines Floats aufgrund der Art und Weise, wie Exponent und Mantisse arbeiten, nicht besonders zuverlässig. Wenn Sie also eine bessere Genauigkeit wünschen, verwenden Sie Doubles, aber erwarten Sie auch keine perfekte Genauigkeit von ihnen.

Verwandte Themen