你能装饰一个十六进制常量,让它被解释为一个浮点数吗?

Posted

技术标签:

【中文标题】你能装饰一个十六进制常量,让它被解释为一个浮点数吗?【英文标题】:Can you decorate a hexadecimal constant so it's interpreted as a float? 【发布时间】:2011-08-01 23:17:06 【问题描述】:

只是对某事感到好奇。在将 html 颜色(其单个颜色分量通过 2 位十六进制值表示)转换为 0.0 到 1.0 之间的浮点数以便我们可以将它们与 OpenGL 一起使用时,我开始好奇一些事情。我们必须将十六进制值除以 255 才能得到对应的 OpenGL 值,但我们不能简单地按原样使用十六进制值,因为这会产生整数除法。

现在我知道这些都可以解决这个问题(当然)......

float r = 0xFD / (float)0xFF; // Works because of the cast to float

float r = 0xFD / 255.0f;      // Works because of the explicit float 

float d = 0xFF;
float r = 0xFD / d;           // Works because 'd' is a float 

...但我想知道是否有任何方法可以仅装饰一个十六进制值,以便将其解释为浮点数(就像您在 1.0f 中使用 'f' 所做的那样),而无需进行强制转换、计算或临时变量。

这些当然行不通……

float r = 0xFD / 0xFF;   // Integer division yields an integer, not float

float r = 0xFD / 0xFFf;  // Interprets 'f' as part of the hex value

同样,不要试图找出如何实现我需要的结果,因为我的代码运行良好。我只是想知道我是否可以通过使用类似于'f'如何处理十进制值而不是使用上述三种有效的方法来装饰十六进制值来使代码更清晰。

【问题讨论】:

我很好奇:为什么你在着色器中经常使用文字足够重要?您多久需要一次特定的常量颜色? 不是着色器。从来没有说过它是并且实际上是与渲染完全无关的程序的一个完全不同的部分(除了我正在定义颜色。)不过,这与问题无关。忘了我什至提到了OpenGL。我只是想看看有没有办法装饰十六进制。我想这更像是一个与编译器相关的问题。 【参考方案1】:

这可能在 c++0x 中使用 user defined literals 是可能的,但我怀疑在 c++03 中是否有任何巧妙的方法。

【讨论】:

从来没有听说过 c++0x,只是找到了 Wikipedia 上的文章。 en.wikipedia.org/wiki/C%2B%2B0x 真的很酷的东西!投了赞成票!【参考方案2】:

恐怕您必须使用预处理器定义才能获得最佳外观。而且你还需要强制转换来执行你的计算。

我能想到的最好的解决方案是

#define COMPONENT8(value) ((float)(value) / 255.0f))

浮点值不能指定为十六进制(整数)值。

【讨论】:

虽然这不能回答我的具体问题,但我什至没有想过使用定义来实际容纳这样的实际整个方程!很酷! (......虽然我想我会称它为NormalizeHex 或类似的东西,因为这就是它实际上在做的事情。)但是......你为什么要将value 转换为浮点数?分母(此处为“255.0f”)是否足以迫使整个事物成为浮点除法?我的意思是这只是一个演员表,但我认为它实际上并不需要。 再一次,现在我想起来了(以及我之前没想过这样做的原因......)是为什么你不在这里使用内联函数而不是定义?当它被内联时,实际编译的结果不是基本一样吗? 对定义与内联函数有何评论?我投票给你作为答案,但我仍然很好奇你为什么要那样做。我能想到的唯一一件事是定义只需要一个头文件,而内联函数也需要一个代码文件。此外,您还可以使用内联函数进行完整的类型检查。 是的,它只是一个演员表。我更喜欢预处理器,因为我觉得它更舒服,但我认为内联函数没有任何限制......【参考方案3】:

我不知道有什么方法可以完全按照您的要求进行操作,但是如果您希望重复使用 0xFF,为什么不将其设置为常量?这仍然会保留打字,即:

const float divisor = 0xFF
float r = 0xFD / divisor

我认为这可以解决您想要解决的问题,即使它的方式并不完全相同。

【讨论】:

谢谢,但我不想解决这个问题。我正在尝试寻找是否有办法装饰十六进制值以使其成为浮点数。您所展示的只是很好的编程(尽管是编程 101),但由于您的回答,我会将问题更改为更清楚。【参考方案4】:

你可以做到这一点的一种方法是定义你自己的模式来定义十六进制浮点数,0xff 定义十六进制整数,你可以制作一个宏,比如:

#define 0y (float) 0x

那你就写

float r = 0xAF / 0yFF;

进行浮点除法。

这个解决方案可能会给阅读您的代码的其他人造成混乱,但如果代码主要是为您准备的,那么您可以这样做

【讨论】:

当我读到它时,这看起来非常酷……但是……不起作用!首先,显然你不能用数字开始定义,其次,它不喜欢 '0x' 部分指出它不将 'x' 识别为整数修饰符。另外,0y 后面没有空格,它与定义不匹配。伙计……我太想把这个标记为被接受了,因为它是如此简单的优雅。猜想这太简单了。让我知道你是否让这个工作。 (仅供参考,我尝试了#define f0x (float)0x,但由于上述原因无济于事。) 哦,太糟糕了。好吧,因为我在工作,所以我不可能测试任何 atm,但我今晚回家时可能会看看。

以上是关于你能装饰一个十六进制常量,让它被解释为一个浮点数吗?的主要内容,如果未能解决你的问题,请参考以下文章

java浮点数常量是啥

printf格式化字符输出对应解释

使用带有浮点数的 pandas reindex:插值

浮点数的十六进制表示

浮点数在c中的基数排序

如何在 Java 中将整数转换为浮点数?