Java 比例编号为<;=255?

Java 比例编号为<;=255?,java,language-agnostic,math,distribution,Java,Language Agnostic,Math,Distribution,我有一些单元格,其数值可以是介于0和Integer.MAX\u value之间的任何值。我想对这些单元格进行相应的颜色编码 如果该值为0,则r=0。如果该值为整数.MAX_值,则r=255。但两者之间的价值又如何呢 我想我需要一个极限为x=>整数的函数。最大值是255。这个函数是什么?还是有更好的方法 我可以只做(value/(Integer.MAX\u value/255)),但这会导致许多低值为零。所以,也许我应该用一个log函数来实现它 我的大多数值都在[0,10000]范围内。因此,我想

我有一些单元格,其数值可以是介于0和
Integer.MAX\u value
之间的任何值。我想对这些单元格进行相应的颜色编码

如果该值为0,则r=0。如果该值为
整数.MAX_值
,则r=255。但两者之间的价值又如何呢

我想我需要一个极限为x=>
整数的函数。最大值是255。这个函数是什么?还是有更好的方法

我可以只做
(value/(Integer.MAX\u value/255))
,但这会导致许多低值为零。所以,也许我应该用一个log函数来实现它

我的大多数值都在[0,10000]范围内。因此,我想强调其中的差异

我可以只做(value/(Integer.MAX_value/255)),但这会导致许多低值为零

您可以采取的一种方法是使用模运算符(
r=value%256;
)。虽然这不能确保
Integer.MAX\u值
变成255,但它可以保证一个介于0和255之间的数字。它还允许在0-255范围内分配较低的数字

编辑:


有趣的是,当我测试这个时,
Integer.MAX_值%256
确实会导致
255
(我最初错误地测试了
%255
,结果是错误的)。这似乎是一个非常直截了当的解决方案

您要查找的值是:r=255*(value/Integer.MAX\u value)。因此,您必须将其转换为双精度,然后再转换回整数。

一般来说(因为我不清楚这是否是一个Java或语言不可知的问题),您可以将您的值除以
整数。MAX_value
,乘以
255
,然后转换为整数。

这是可行的<代码>r=值/8421504

8421504实际上是“魔法”数字,等于最大值/255。因此,MAX_VALUE/8421504=255(还有一些变化,但足够小的整数数学将消除它)

如果您想要一个没有幻数的,这应该可以工作(并且性能相同,因为任何好的编译器都会用实际值替换它:

r=value/(Integer.MAX_value/255);

好的方面是,这不需要任何浮点值。

最公平的线性缩放实际上是这样做的:

floor(256 * value / (Integer.MAX_VALUE + 1))
请注意,这只是伪代码,并假定为浮点计算

如果我们假设Integer.MAX_值+1是2^31,并且/将给我们整数除法,那么它将简化为

value / 8388608
为什么其他答案是错误的

一些答案(以及问题本身)暗示了
(255*value/Integer.MAX_value)
的变化。可能必须使用
round()
floor()
将其转换为整数

如果使用
floor()

如果使用
round()

使用我上面提到的缩放方法,不会出现这样的问题

非线性方法

如果要使用日志,请尝试以下操作:

255 * log(value + 1) / log(Integer.MAX_VALUE + 1)

您也可以只取值的平方根(这不会一直到255,但如果您愿意,可以将其放大)。

最佳答案实际上取决于您想要的行为

如果您希望每个单元格的颜色通常与相邻单元格的颜色不同,请按照第二段中akf的说法使用模(x%256)

如果你想让颜色对实际值有一些影响(比如“蓝色意味着较小的值”一直到“红色意味着巨大的值”),你必须发布一些关于你期望的值分布的信息。因为你担心许多低值为零,我可能猜你有很多,但那只是一个猜测


在第二个场景中,您确实希望将可能的回答分为256个“百分位数”,并为每个“百分位数”指定一种颜色(每个百分位数中可能的回答数相等).

对于0-2^32到0-255范围内的线性映射,只需获取高阶字节。以下是使用二进制
&
和位移位的效果:

r = value & 0xff000000 >> 24
使用mod 256肯定会返回一个0-255的值,但您无法从结果中得出任何分组意义-1257、513、1025都将映射到缩放值1,即使它们彼此相距很远

如果希望在低值之间更具区分性,并将更多的大值合并在一起,则日志表达式将起作用:

r = log(value)/log(pow(2,32))*256
编辑:哎呀,我的高中代数老师Buckenmeyer夫人会晕倒的!
log(pow(2,32))
32*log(2)
相同,而且评估成本更低。现在我们还可以更好地考虑这一点,因为256/32是一个不错的8:

r = 8 * log(value)/log(2)
log(value)/log(2)
实际上是
log-base-2的value
,这个log对我们来说非常简洁:

r = 8 * log(value,2)

好了,Buckenmeyer夫人-你的努力并没有完全白费!

如果你抱怨低数值变为零,那么你可能希望将数值标准化为255,而不是整个数值范围

公式将变成:


currentValue/(集合的最大值)

请注意,如果您想要越来越亮,亮度不是线性的,因此从值到颜色的直接映射将不会产生好的结果


“颜色”类有一种使颜色更亮的方法。请看一看。

这些答案中的大多数都讨论了线性实现,Artelius的答案似乎是最好的。但最好的公式取决于您试图实现的内容和值的分布。如果不知道,很难给出一个理想答案

但是绝对
r(x) = floor(((11.5553 * log(14.4266 * (x + 1.0))) - 30.8419) / 0.9687)
r(x) = floor(255 * log(x + 1) / log(2^31 + 1)