2017-07-26 40 views
1

我寫轉換三個數的函數(R,G,B)到用於通過java.awt.Color長投射到整型內部功能

(defn to-rgb 
    ([r g b] (bit-or 
      (long 4278190080) ; the alpha channel = (bit-shift-left 255 24) 
      (bit-shift-left r 16) 
      (bit-shift-left g 8) 
      b))) 

使用Color構造和.getRGB

一個整數
bitmap> (.getRGB (Color. 0 0 0)) 
-16777216 
bitmap> (type (.getRGB (Color. 0 0 0))) 
java.lang.Integer 
(Integer/toBinaryString (.getRGB (Color. 0 0 0))) 
"11111111000000000000000000000000" 

然後我的版本。所以我需要強制轉換爲Integer

bitmap> (to-rgb 0 0 0) 
4278190080 
bitmap> (Integer. (to-rgb 0 0 0)) 
-16777216 ; as expected 

所以我決定把函數內部的投因爲我總是希望Integer返回。

(defn to-rgb2 
    ([r g b] (Integer. (bit-or 
         (long 4278190080) 
         (bit-shift-left r 16) 
         (bit-shift-left g 8) 
         b)))) 

bitmap> (to-rgb2 0 0 0) 
IllegalArgumentException Value out of range for int: 4278190080 clojure.lang.RT.intCast (RT.java:1205) 

回答

3

在Java中,Integer只有32位。將其更改爲Long

(Long. ...) 

的問題是不斷4278190080轉化爲0xFF000000十六進制,在這裏我們看到,最左邊的位設置。在Java中,由於整數值是32位有符號的,所以最左邊的位不能被設置,因爲它被保留爲二進制補碼錶示的負數。

java.lang.Integer.MAX_VALUE = 0x7FFFFFFF 

in hex。


更新

如果你需要它作爲一個32位的值,使用Long.intValue()像這樣:

(defn to-rgb3 
    ([r g b] (.intValue 
      (Long. (bit-or 
         (long 4278190080) 
         (bit-shift-left r 16) 
         (bit-shift-left g 8) 
         b))))) 
(dotest 
    (spyxx (to-rgb3 0 0 0))) 

(to-rgb3 0 0 0) => java.lang.Integer->-16777216 
+0

,但我需要它來自鑄造價值'-16777216'長到一個整數。它應該匹配'(.getRGB(Color。0 0 0))'' – beoliver

+0

的返回值我認爲我的編輯更清晰了嗎?我的問題是爲什麼在一個函數之外的一個工作*工作*(是的它轉換爲負),但不是在裏面? – beoliver

+0

'.intValue'就是我一直在尋找的東西:) – beoliver