부호 있는 문자에서 부호 없는 문자로 변환하고 다시 돌아오시겠습니까?
저는 JNI에서 일하고 있으며 jbyte의 배열을 가지고 있습니다.jbyte는 -128~127의 부호 있는 문자로 표현됩니다.jbytes는 이미지 픽셀을 나타냅니다.화상 처리의 경우, 통상, 픽셀 컴퍼넌트의 범위는 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++가 포함되어 있습니다.static_cast
★★★★★★★★★★★★★★★★★」reinterpret_cast
부호 없는 변수에서 부호 없는 변수로의 변환은 부호 없는 변수 + 1의 최대값으로 부호 없는 변수의 값을 포함하도록 지시하는 것을 의미할 수 있습니다., 부호 이면 ", "char " -128" 입니다.CHAR_MAX+1
"128" "-1" 입니다.CHAR_MAX+1
255번입니다.스태틱 캐스트 시스템에서 되고 있는 있는 에 관계없이, 일부 없는 하는 것을 할 수 , 「」이 경우, 「」( 「」)입니다.0b10000000
128, 128, 255로 해야 합니다.0b11111111
resterfret_cast는 resterfret_cast를 resterfret_cast로
이이 -128로 에 -128이.0b10000000
은 -1로 됩니다.0b11111111
그리고 그 사이에 있는 모든 사람들에게도 마찬가지입니다.그러나 다른 컴퓨터(일반적으로 오래된 아키텍처)에서는 부호 및 규모, 보 등 다른 부호 표현을 사용할 수 있습니다.0b10000000
-128이므로 bit value가 .리프레트 캐스트 128자 덧붙여서, addition addition addition addition addition addition addition addition addition addition addition addition addition addition addition.0b11111111
는 -1이 이 bit value가 bit value가 -1인 됩니다(이 값은 static_cast.bit value가 됩니다).보어의 경우 부호 없는 값 128은 -0의 값으로 인해 -127에서 127의 범위이기 때문에 실제로는 부호 있는 문자로 나타낼 수 없습니다.
대부분의 컴퓨터가 2의 보완을 사용하고 있기 때문에 코드 실행이 가능한 거의 모든 장소에서 문제 전체를 해결할 수 있습니다.매우 오래된 아키텍처에서는 2개의 보완 이외의 것을 가진 시스템을 볼 수 있을 것입니다.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 언어에서는 정수 승격이라는 기능을 사용하여 계산을 수행하기 전에 값의 비트 수를 늘립니다.따라서 CLAMP255 매크로는 정수(아마 32비트) 정밀도로 작동합니다.결과는 jbyte에 할당되어 정수 정밀도가 jbyte에 맞는 8비트로 감소합니다.
CLAMP255는 v < 0에 대해 0을 반환하고 v > = 0에 대해 255를 반환한다는 것을 알고 계십니까?
는 IMHO, CLAMP255로.
#define CLAMP255(v) (v > 255 ? 255 : (v < 0 ? 0 : v))
차이점:v가 255보다 크고 0보다 작으면 255 대신 v를 반환합니다.
입력 데이터를 해석하는 방법에는 두 가지가 있습니다. -128은 가장 낮은 값이고 127은 가장 높은 값(즉, 진정한 서명된 데이터) 또는 0은 가장 낮은 값이고 127은 중간 값이며 다음 "높은" 숫자는 -128이며 -1은 "가장 높은" 값(즉, 가장 유의한 비트가 두 개의 컴포트에서 이미 신호 비트로 잘못 해석되었습니다).리스먼트 표기법
후자를 의미한다고 가정할 때, 공식적으로 올바른 방법은
signed char in = ...
unsigned char out = (in < 0)?(in + 256):in;
적어도 GCC는 수술 불가로 인식합니다.
제가 당신의 질문을 이해했는지 100% 확신할 수 없으니, 제가 틀렸다면 말해주세요.
제가 맞췄다면 기술적으로는 부호화된 문자이지만 실제로는 0에서 255 사이의 픽셀 값을 읽고 있습니다.그리고 프로세스에서 값을 손상시키지 않고 어떻게 처리해야 하는지 궁금할 것입니다.
Then, you should do the following:
convert jbytes to unsigned char before doing anything else, this will definetly restore the pixel values you are trying to manipulate
use a larger signed integer type, such as int while doing intermediate calculations, this to make sure that over- and underflows can be detected and dealt with (in particular, not casting to a signed type could force to compiler to promote every type to an unsigned type in which case you wouldn't be able to detect underflows later on)
when assigning back to a jbyte, you'll want to clamp your value to the 0-255 range, convert to unsigned char and then convert again to signed char: I'm not certain the first conversion is strictly necessary, but you just can't be wrong if you do both
For example:
inline int fromJByte(jbyte pixel) {
// cast to unsigned char re-interprets values as 0-255
// cast to int will make intermediate calculations safer
return static_cast<int>(static_cast<unsigned char>(pixel));
}
inline jbyte fromInt(int pixel) {
if(pixel < 0)
pixel = 0;
if(pixel > 255)
pixel = 255;
return static_cast<jbyte>(static_cast<unsigned char>(pixel));
}
jbyte in = ...
int intermediate = fromJByte(in) + 30;
jbyte out = fromInt(intermediate);
ReferenceURL : https://stackoverflow.com/questions/5040920/converting-from-signed-char-to-unsigned-char-and-back-again
'source' 카테고리의 다른 글
strncpy가 null로 종료되지 않는 이유는 무엇입니까? (0) | 2022.08.21 |
---|---|
VueJS 오류: 프로펠을 직접 변환하지 마십시오. (0) | 2022.08.21 |
디렉토리의 모든 파일 삭제(디렉토리 제외) - 1개의 라이너 솔루션 (0) | 2022.08.21 |
상위 컴포넌트에서 Vue.js 기능 컴포넌트에 클래스를 적용하는 방법 (0) | 2022.08.21 |
어떤 경우에 JPA @JoinTable 주석을 사용합니까? (0) | 2022.08.21 |