从符号的字符转换为unsigned char型,然后再返回? [英] Converting from signed char to unsigned char and back again?

查看:143
本文介绍了从符号的字符转换为unsigned char型,然后再返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用JNI工作,并具有类型jbyte,其中jbyte重新psented作为一个符号字符,即$ P $范围从-128到127 jbytes重新present图像的像素阵列。对于图像处理,我们通常希望像素组件范围为0,因此到255我要的jbyte值转换为范围在0到255(即同一范围内的无符号字符),做了一些价值计算,然后存储作为结果再次jbyte。

I'm working with JNI and have an array of type jbyte, where jbyte is represented as an signed char i.e. ranging from -128 to 127. The jbytes represent image pixels. For image processing, we usually want pixel components to range from 0 to 255. I therefore want to convert the jbyte value to the range 0 to 255 (i.e. the same range as unsigned char), do some calculations on the value and then store the result as a jbyte again.

我怎样才能做到这些转换安全?

How can I do these conversion safely?

我设法得到这个code的工作,其中像素值由30增加,但钳位值255,但如果它的安全或便携式我不明白:

I managed to get this code to work, where a pixel value is incremented by 30 but clamped to the value 255, but I don't understand if it's safe or portable:

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

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

我想知道如何在C和C ++做到这一点。

I'm interested to know how to do this in both C and C++.

推荐答案

这也是为什么C ++引入的新投的风格,其中包括的static_cast 和的原因之一 reinter pret_cast

This is one of the reasons why C++ introduced the new cast style, which includes static_cast and reinterpret_cast

有就是你可能意味着两件事情说转换,从符号到无符号,你可能会说你希望的无符号变量包含已签署的可变模的值(你的无符号类型+ 1的最大值)。也就是说,如果你的符号字符有-128那么 MAX_CHAR + 1 添加了对值为128,如果它有值-1,则<$ C值$ C> MAX_CHAR + 1 添加了对值为255,这是什么的static_cast完成。在另一方面,你可能意味着无论再presentation符号整数的系统上使用国米preT一些变量引用是PTED为一个无符号字节间$ P $内存的位值,也就是说,如果有位值 0b10000000 应该评估为价值128和255位值 0b11111111 ,这是完成与reinter pret_cast。

There's two things you can mean by saying conversion from signed to unsigned, you might mean that you wish the unsigned variable to contain the value of the signed variable modulo (the maximum value of your unsigned type + 1). That is if your signed char has a value of -128 then MAX_CHAR+1 is added for a value of 128 and if it has a value of -1, then MAX_CHAR+1 is added for a value of 255, this is what is done by static_cast. On the other hand you might mean to interpret the bit value of the memory referenced by some variable to be interpreted as an unsigned byte, regardless of the signed integer representation used on the system, i.e. if it has bit value 0b10000000 it should evaluate to value 128, and 255 for bit value 0b11111111, this is accomplished with reinterpret_cast.

现在,两个补重presentation发生这种情况是完全一样的东西,因为-128重新psented为 0b10000000 $ P $和-1是psented为 0b11111111 重新$ p $,同样为所有在两者之间。但是,其他计算机(通常较旧的架构)可以使用不同的重新签订presentation如标志和幅度或一补数。在一补数的 0b10000000 bitvalue不会是-128,-127,但是,这样一个静态强制转换为无符号的字符将使这个129,而reinter pret_cast会使这个128.另外在一补数的 0b11111111 bitvalue不会是-1,但-0,(是这个值存在于一补数,)和将被转换为0与的static_cast的值,但是255与reinter pret_cast的值。注意,在一个符号的字符psented一补数的128的无符号的值实际上不被重新$ P $的情况下,由于它的范围从-127到127,由于-0值

Now, for the two's complement representation this happens to be exactly the same thing, since -128 is represented as 0b10000000 and -1 is represented as 0b11111111 and likewise for all in between. However other computers (usually older architectures) may use different signed representation such as sign-and-magnitude or ones' complement. In ones' complement the 0b10000000 bitvalue would not be -128, but -127, so a static cast to unsigned char would make this 129, while a reinterpret_cast would make this 128. Additionally in ones' complement the 0b11111111 bitvalue would not be -1, but -0, (yes this value exists in ones' complement,) and would be converted to a value of 0 with a static_cast, but a value of 255 with a reinterpret_cast. Note that in the case of ones' complement the unsigned value of 128 can actually not be represented in a signed char, since it ranges from -127 to 127, due to the -0 value.

我不得不说,绝大多数的电脑将使用补做的任何地方你的code将永远运行整个问题没有实际意义。您可能会只看到过比补之外的任何系统很老的架构,认为60年代的时间表。

I have to say that the vast majority of computers will be using two's complement making the whole issue moot for just about anywhere your code will ever run. You will likely only ever see systems with anything other than two's complement in very old architectures, think '60s timeframe.

语法归结为以下几点:

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 ++的方式与数组做到这一点:

To do this in a nice C++ way with arrays:

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

或Ç方式:

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

这篇关于从符号的字符转换为unsigned char型,然后再返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆