我正在使用JNI,有一个jbyte类型的数组,其中jbyte表示为一个有符号字符,即从-128到127.字节代表图像像素.对于图像处理,我们通常希望像素分量在0到255之间.因此,我想将jbyte值转换为0到255的范围(即与无符号字符相同的范围),对该值进行一些计算,然后再次将结果存储为jbyte.

如何安全地进行这些转换?

我设法让这段代码起作用,其中一个像素值增加了30,但被限制为255,但我不知道它是安全的还是便携的:

 #define CLAMP255(v) (v > 255 ? 255 : (v < 0 ? 0 : v))

 jbyte pixel = ...
 pixel = CLAMP_255((unsigned char)pixel + 30);

我很想知道如何在C和C++中做到这一点.

推荐答案

这是C++引入新的Casic风格的原因之一,包括static_castreinterpret_cast.

从有符号到无符号的转换有两个意思,你可能希望无符号变量包含有符号变量的值,该值除以无符号类型的最大值+1.也就是说,如果您的签名字符的值为-128,那么将为128的值添加CHAR_MAX+1,如果它的值为-1,那么将为255的值添加CHAR_MAX+1,这就是静态_cast所做的.另一方面,您可能意味着将某个变量引用的内存的位值解释为无符号字节,而不管系统上使用的是有符号整数表示,也就是说,如果它的位值为0b10000000,则应计算为128,而位值为0b11111111,则应计算为255,这是通过重新解释_cast实现的.

现在,对于二者的补码表示,这恰好是完全相同的事情,因为-128表示为0b10000000,-1表示为0b11111111,对于两者之间的所有事物也是如此.然而,其他计算机(通常是较旧的体系 struct )可能会使用不同的符号表示,例如符号和大小或1的补码.在one的补码中,0b10000000位的值不是-128,而是-127,因此对unsigned char的静态转换将使其为129,而对reinterpret_的转换将使其为128.此外,在"一"的补码中,0b11111111位的值不是-1,而是-0(是的,这个值存在于"一"的补码中),并将通过静态转换转换为0,但通过重新解释转换转换为255.注意,在"1"补码的情况下,128的无符号值实际上不能用有符号字符表示,因为它的范围是-127到127,这是由于-0的值.

我不得不说,绝大多数计算机将使用二的补码,这使得整个问题在你的代码运行的任何地方都变得毫无意义.在非常古老的体系 struct 中,你可能只会看到除了两个系统之外的任何系统,想想60年代的时间框架.

语法可归结为以下几点:

signed char x = -100;
unsigned char y;

y = (unsigned char)x;                    // C static
y = *(unsigned char*)(&x);               // C reinterpret
y = static_cast<unsigned char>(x);       // C++ static
y = reinterpret_cast<unsigned char&>(x); // C++ reinterpret

用一个好的C++方式来做这些事情:

jbyte memory_buffer[nr_pixels];
unsigned char* pixels = reinterpret_cast<unsigned char*>(memory_buffer);

或者C方式:

unsigned char* pixels = (unsigned char*)memory_buffer;

C++相关问答推荐

如何从C中的公钥字符串创建EVP_PKEY

当包含头文件时,gcc会发出隐式函数声明警告

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

如何判断宏参数是否为C语言中的整型文字

为什么双重打印与C中的float具有不同的大小时具有相同的值?

我的程序在收到SIGUSR1信号以从PAUSE()继续程序时总是崩溃()

Clang警告称,`ffi_type`与`sizeof`不兼容

为什么将函数名括在括号中会禁用隐式声明?

C代码在字符串中删除不区分大小写的子字符串的问题

接受任何参数的函数指针是否与接受不同参数的函数兼容

';\n&39;和';\r&39;中的';\n&39;之间有什么关系?

For循环不会迭代所有字符串字符吗?(初学者问题)

C中的回文数字

基于蝶数恰好有8个除数的事实的代码

使用mmap为N整数分配内存

未使用sem_open正确初始化信号量

哪些C++功能可以在外部C块中使用

访问未对齐联合的成员是否为未定义行为,即使被访问的成员已充分对齐?

无法将字符串文字分配给 C 中的字符数组

10 个字节对于这个 C 程序返回后跳行的能力有什么意义