在内部函数中转换为Integer

时间:2017-07-26 19:13:25

标签: clojure casting long-integer

我正在编写一个函数,将三个数字(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)

1 个答案:

答案 0 :(得分:3)

在Java中,Integer只有32位。将其更改为Long

(Long. ...)

问题是常量4278190080转换为十六进制0xFF000000,我们看到最左边的位已设置。在Java中,由于整数值是32位的符号,因此无法设置最左边的位,因为它是以二进制符号表示为负数保留的。

java.lang.Integer.MAX_VALUE = 0x7FFFFFFF

十六进制。

<强>更新

如果您需要它作为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