2017-01-25 2 views
2

Я делаю игру, в которой я устанавливаю местоположение с поплавком, проблема в том, что поплавок не поднимается выше 255? Это, как я делаю поплавок идти выше: метод 1. надстройку:Поплавок не может превышать 256?

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

2. метод обновления

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(); 
    } 

Обновление который вызывается в цикле в то время как в детской теме ,

Это то, что я использую поплавок для

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(); 
} 

Это renderLocaiton переменная. Я не останавливаю его, чтобы подняться выше.

+1

* Что-то * есть, и что-то не является внутренним представлением поплавков. –

+0

@DaveNewton вы уверены? Мне было бы интересно, достаточно ли 'float' для представления' 255.00001f' в отличие от '255f'. –

+0

@LouisWasserman \t Конечно, но это не тот вопрос, который задает вопрос - OP говорит, что он не перейдет через 256. Или 255, в зависимости от того, какое предложение вы читаете. –

ответ

3

float только имеет ~ 6 цифр точности. Я предлагаю, используя int и деления на 100000 или с помощью double

При добавлении 1e-5f к 256f ответ 256f как это ближе всего представляют, в состоянии значение. У вас такая же проблема с двойным, но в гораздо более высокой точке. Если вы добавите 1e-5 в 137438953472 то же самое произойдет, поскольку вы работаете за пределами точности double.

Если вы используете int, у вас возникнет другая проблема. Добавить 1 в 2147483647 и int переливается в -2147483648

КСТАТИ У вас есть проблемы с поплавком, прежде чем достичь 256. Из-за ошибки 128f + 1e-5f == 128.00002 представления, которые я подозреваю, это не то, что вы хотели.

Фактически, если вы продолжаете добавлять 1e-5f, для увеличения между целыми значениями/целыми числами потребуется всего 65536 раз, а не 100 000, которые вы могли ожидать.

Полезно знать пределы ваших типов.

1

Добавление ответа Петровской, это является обязательным для чтения: What every computer scientist should know about floating-point arithmetic

Что происходит в основном 256.00001f получает округляется до 256f (255.00001f, с другой стороны, округляется до 255.00002f). Вы можете сохранить 256.00002f, но он будет округлен до 256.00003f. Первое округление down происходит в 256.00001f, и именно там вы достигли предела, поэтому любое другое добавление 0,00001 не будет иметь эффекта (каждый раз, когда вы его добавляете, он будет отброшен из-за округления). Как вы могли заметить, из-за того, что показатель экспоненты и мантиссы работает в пятом десятичном разряде от поплавка, он не является особенно надежным, поэтому, если вам нужна более высокая точность, используйте удвоения, но не ожидайте от них идеальной точности.

Смежные вопросы