Clojure中数字的无符号比较?

时间:2011-12-22 00:32:48

标签: clojure comparison integer

我正在尝试在Clojure中编写一个图像处理库,但在编写测试时我遇到了一个问题。

图像数据存储为整数的2D数组,这些整数是有符号的(Java,扩展名为Clojure,没有无符号整数)。我有一个函数来获取给定坐标对的像素。我对该函数的测试看起来像这样:

(is (= (get-pixel image 0 (dec width)) 0xFFFF0000))

即,查看(0,width-1)处的像素是否为红色。问题是,get-pixel返回一个signed int,但Clojure将0xFFFF0000视为long。在这种情况下,get像素返回-65536(十六进制为0xFFFF0000),Clojure正在检查它是否等于4294901760。

现在,我有几个选择。我可以使用十六进制的有符号整数解释作为小数(-65536)重写测试,但我认为这使得测试的意图不太清楚。我可以编写一个函数来将负数转换为正数,但这是一个复杂的附加层。最简单的方法可能就是在两个数字之间做一个按位,然后查看它是否有变化,但这看起来仍然比它应该更复杂。

是否有任何内置方法强制0xFFFF0000被评估为有符号整数而不是长整数,或者对两个任意数字进行逐位比较? int函数不起作用,因为该数字太大而无法表示为signed int。

谢谢!

2 个答案:

答案 0 :(得分:4)

在clojure 1.3中,有一个unchecked-int函数,它只占用最后四个字节并使它们成为一个int:

user> (unchecked-int 0xffff0000)
-65536

Clojure不允许您输入不同大小的字面数字,这有点令人伤心 - 这里我们做的是等同于Java (int)0xffff0000L

答案 1 :(得分:0)

你使用什么样的clojure版本?在1.3版本中,原始处理方式发生了很大变化。我做了一些实验,似乎得到的结果与你描述的不同。

user=> (int 0xFFFF0000)
IllegalArgumentException Value out of range for int: 4294901760  clojure.lang.RT.intCast (RT.java:1093)
user=> (long 0xFFFF0000)
4294901760
user=> *clojure-version*
{:major 1, :minor 3, :incremental 0, :qualifier nil}

如果您使用的是1.3,则可以使用long功能。您还可以使用ByteBuffer操作数据并更直接地处理字节,尽管您将永远无法获得使用C的控制级别。