2016-08-22 18 views
1

不知道我是如何完成的學校不能夠解決這個小問題...簡單的代碼 - 錯誤讓我瘋了......浮到2個字節,回

下面的代碼會產生意想不到的輸出:

public Color getPixel(int x, int y){ 
    return img.getPixelReader().getColor(x, y); 
} 
public float colorToHeight(Color c){ 
    int b =(int)(c.getBlue()*256); 
    int r =(int)(c.getRed()*256*256); 
    float h = (b+r)/2; 
    h-=10000; 
    return h; 
} 
public Color heightToColor(float h){ 
    h+=10000; 
    h*=2;   
    double r= (int)(h/(256)); 
    double b = h-(r*256); 
    return new Color(r/256,0,b/256,1f); 
} 
public void debugPixel(int x, int z){ 

    System.out.println("test 424->Color: "+heightToColor(424f)); 
    System.out.println("test Color->424: "+colorToHeight(heightToColor(424f))); 
    System.out.println("test Color->424->Color: "+heightToColor(colorToHeight(heightToColor(424f)))); 
    System.out.println("check A: "+getPixel(x,z) + " Height: "+colorToHeight(getPixel(x,z))); 
    System.out.println("check B: "+heightToColor(colorToHeight(getPixel(x,z)))); 
    System.out.println("check C: "+getPixel(x,z)); 
} 

輸出:

test 424->Color: 0x510070ff 
test Color->424: 424.0 
test Color->424->Color: 0x510070ff 
check A: 0x5200cbff Height: 638.0 
check B: 0x53001cff 
check C: 0x5200cbff 

我絕對不找原因【檢查B]的原因= [查看A] ....謝謝!

+0

注意'float <-> int'轉換,包括整數除法'/'。這是相當肯定**值不會相同。 – charlie

+0

哪個'Color'類是這個? (I假設這個類做內部一些夾緊,尤其是導致「紅色」成分,這很可能超出範圍,將被鉗位到[0.0,1.0]) – Marco13

+0

...我想我發現它....認爲這是一個愚蠢的錯誤,正確的INT-漂浮的色彩(INT)Math.round((c.getBlue()* 255)),發現它的顏色類中。現在這個錯誤在我的支票中只有1,所以在某處會出現舍入錯誤。 – SalkinD

回答

0

首先,固定師:

float h = (b + r)/2f; 

原代碼首先執行整數除法,然後將其轉換爲浮動,例如(1 + 2)/2 == 1.0。修復後,它評估爲(1 + 2)/2.0 == 1.5

因此,在第二個測試案例的高度應爲:

red = 83 
blue = 29 
height = 638.5 

雖然與不正確的整數除法:

height = 638.0 // 0.5 truncated off 
red = 83 
blue = 28 // while 29 is expected 

關於RGB邊界,如果Color類的範圍內操作0..255,定影時,由於需要2不同常量—一個RGB上LIMIT,並且該組合物照顧:

private static final int LIMIT = 255; 
private static final int SHIFT = 256; // or whatever > LIMIT, e.g. 1000 

public float colorToHeight(Color c){ 
    int b = (int) Math.round(c.getBlue() * LIMIT); 
    int r = (int) Math.round(c.getRed() * LIMIT); 
    float h = (b + r * SHIFT)/2f; 
    h -= 10000; 
    return h; 
} 

public Color heightToColor(float h){ 
    h += 10000; 
    h *= 2;   
    double r = (int) (h/SHIFT); 
    double b = h - (r * SHIFT); 
    return new Color(r/LIMIT, 0, b/LIMIT, 1f); 
} 
+0

感謝您的幫助和解決方案摘要! – SalkinD

1

由於後面的操作(colorToHeightheightToColor)涉及浮點操作,因此無法確定您獲得的值是否相同,因此會發生精度損失。

你可以重寫你的方法,而無需使用浮點,不是因爲所有的部門,甚至可以用轉移來完成。

public int colorToHeight(Color c){ 
    int b = c.getBlue()>>8; 
    int r = c.getRed()>>16; 
    int h = (b+r)/2; // will be an integer, b and r are even 
    h-=10000; 
    return h; 
} 
public Color heightToColor(int h){ 
    h+=10000; 
    h*=2;   
    int r= h>>8; 
    int b = h-(r<<8); 
    return new Color(r>>8,0,b>>8,1f); 
} 
+0

我可以問你在哪裏看到他的代碼比較? – SomeJavaGuy

+0

thats no pointer,thats Color對象的toString方法,它的0xRRGGBBFF – SalkinD

+2

仍然沒有比較給定代碼中的任何引用。我的猜測是他爲什麼在檢查A和檢查B後的輸出不同。 – SomeJavaGuy