signed double to unsigned byte: ARM64 versus Win64Iteration over std::vector: unsigned vs signed index variableC++ Binary file read issueExtracting the byte value of double from memoryC - Signed and Unsigned integerWrong sign extension c++/qtUndefined behaviour when using iostream read and signed charRead n bytes in a char array and return it as a doublechar to int conversion mechanismWhy can I pass an int with a value higher than 127 into a char array, but not directly?Properly and portably converting char[4] to uint32_t,int32_t
What does it mean to describe someone as a butt steak?
An academic/student plagiarism
What's the output of a record cartridge playing an out-of-speed record
Can an x86 CPU running in real mode be considered to be basically an 8086 CPU?
How is the claim "I am in New York only if I am in America" the same as "If I am in New York, then I am in America?
What is the offset in a seaplane's hull?
What are the differences between the usage of 'it' and 'they'?
Arthur Somervell: 1000 Exercises - Meaning of this notation
How can bays and straits be determined in a procedurally generated map?
Approximately how much travel time was saved by the opening of the Suez Canal in 1869?
Did Shadowfax go to Valinor?
How did the USSR manage to innovate in an environment characterized by government censorship and high bureaucracy?
The use of multiple foreign keys on same column in SQL Server
Writing rule stating superpower from different root cause is bad writing
What are these boxed doors outside store fronts in New York?
What does "Puller Prush Person" mean?
How does strength of boric acid solution increase in presence of salicylic acid?
Mathematical cryptic clues
What do the dots in this tr command do: tr .............A-Z A-ZA-Z <<< "JVPQBOV" (with 13 dots)
"You are your self first supporter", a more proper way to say it
Is this a crack on the carbon frame?
Today is the Center
Why are electrically insulating heatsinks so rare? Is it just cost?
strToHex ( string to its hex representation as string)
signed double to unsigned byte: ARM64 versus Win64
Iteration over std::vector: unsigned vs signed index variableC++ Binary file read issueExtracting the byte value of double from memoryC - Signed and Unsigned integerWrong sign extension c++/qtUndefined behaviour when using iostream read and signed charRead n bytes in a char array and return it as a doublechar to int conversion mechanismWhy can I pass an int with a value higher than 127 into a char array, but not directly?Properly and portably converting char[4] to uint32_t,int32_t
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
For some legacy reasons I have code that casts a double to unsigned byte and we are seeing much difference between the two platforms. Short of doing - "don't try to stuff a signed value into unsigned value; don't try to stuff a double value in integer", is there something else that can be done?
unsigned char newR1 = -40.16;
Value of newR1 is 216 on windows (as we expected from a long time); but on ARM64 it is 0.
Disassembly on Win:
00007FF75E388818 cvttsd2si eax,mmword ptr [R]
00007FF75E38881D mov byte ptr [newR1],al
On ARM64
00007FF6F9E800DC ldr d16,[sp,#0x38 |#0x38 ]
00007FF6F9E800E0 fcvtzu w8,d16
00007FF6F9E800E4 uxtb w8,w8
00007FF6F9E800E8 strb w8,[sp,#0x43 |#0x43 ]
Will try these as well, but just wanted some other opinions
unsigned char newR1 = -40.16;
unsigned char newR2 = (int)-40.16;
unsigned char newR3 = (unsigned char)-40.16;
unsigned char newR4 = static_cast<int>(-40.16);
or may be
int i = -40.16;
unsigned char c = i;
c++ arm
|
show 2 more comments
For some legacy reasons I have code that casts a double to unsigned byte and we are seeing much difference between the two platforms. Short of doing - "don't try to stuff a signed value into unsigned value; don't try to stuff a double value in integer", is there something else that can be done?
unsigned char newR1 = -40.16;
Value of newR1 is 216 on windows (as we expected from a long time); but on ARM64 it is 0.
Disassembly on Win:
00007FF75E388818 cvttsd2si eax,mmword ptr [R]
00007FF75E38881D mov byte ptr [newR1],al
On ARM64
00007FF6F9E800DC ldr d16,[sp,#0x38 |#0x38 ]
00007FF6F9E800E0 fcvtzu w8,d16
00007FF6F9E800E4 uxtb w8,w8
00007FF6F9E800E8 strb w8,[sp,#0x43 |#0x43 ]
Will try these as well, but just wanted some other opinions
unsigned char newR1 = -40.16;
unsigned char newR2 = (int)-40.16;
unsigned char newR3 = (unsigned char)-40.16;
unsigned char newR4 = static_cast<int>(-40.16);
or may be
int i = -40.16;
unsigned char c = i;
c++ arm
1
What value do you expect to see?
– Mark Ransom
Mar 8 at 4:29
Well 216; -40.16 first become -40; which then becomes 216 preserving the bit pattern representation of -40. That is what everyone except ARM64 is doing - Windows, iOS, Mac. That is the behavior (may be undefined, is it?) I have to come to expect when casting signed/unsigned.
– Amit
Mar 8 at 4:36
what compiler and version?
– old_timer
Mar 8 at 4:41
so.c:5:12: warning: overflow in conversion from ‘double’ to ‘unsigned char’ changes value from ‘-4.0159999999999997e+1’ to ‘0’ [-Woverflow]
– old_timer
Mar 8 at 4:44
Visual Studio 2017 ARM64 compiler targeting Windows machines.
– Amit
Mar 8 at 4:45
|
show 2 more comments
For some legacy reasons I have code that casts a double to unsigned byte and we are seeing much difference between the two platforms. Short of doing - "don't try to stuff a signed value into unsigned value; don't try to stuff a double value in integer", is there something else that can be done?
unsigned char newR1 = -40.16;
Value of newR1 is 216 on windows (as we expected from a long time); but on ARM64 it is 0.
Disassembly on Win:
00007FF75E388818 cvttsd2si eax,mmword ptr [R]
00007FF75E38881D mov byte ptr [newR1],al
On ARM64
00007FF6F9E800DC ldr d16,[sp,#0x38 |#0x38 ]
00007FF6F9E800E0 fcvtzu w8,d16
00007FF6F9E800E4 uxtb w8,w8
00007FF6F9E800E8 strb w8,[sp,#0x43 |#0x43 ]
Will try these as well, but just wanted some other opinions
unsigned char newR1 = -40.16;
unsigned char newR2 = (int)-40.16;
unsigned char newR3 = (unsigned char)-40.16;
unsigned char newR4 = static_cast<int>(-40.16);
or may be
int i = -40.16;
unsigned char c = i;
c++ arm
For some legacy reasons I have code that casts a double to unsigned byte and we are seeing much difference between the two platforms. Short of doing - "don't try to stuff a signed value into unsigned value; don't try to stuff a double value in integer", is there something else that can be done?
unsigned char newR1 = -40.16;
Value of newR1 is 216 on windows (as we expected from a long time); but on ARM64 it is 0.
Disassembly on Win:
00007FF75E388818 cvttsd2si eax,mmword ptr [R]
00007FF75E38881D mov byte ptr [newR1],al
On ARM64
00007FF6F9E800DC ldr d16,[sp,#0x38 |#0x38 ]
00007FF6F9E800E0 fcvtzu w8,d16
00007FF6F9E800E4 uxtb w8,w8
00007FF6F9E800E8 strb w8,[sp,#0x43 |#0x43 ]
Will try these as well, but just wanted some other opinions
unsigned char newR1 = -40.16;
unsigned char newR2 = (int)-40.16;
unsigned char newR3 = (unsigned char)-40.16;
unsigned char newR4 = static_cast<int>(-40.16);
or may be
int i = -40.16;
unsigned char c = i;
c++ arm
c++ arm
edited Mar 8 at 4:41
S.M.
6,30241728
6,30241728
asked Mar 8 at 4:25
AmitAmit
1,543717
1,543717
1
What value do you expect to see?
– Mark Ransom
Mar 8 at 4:29
Well 216; -40.16 first become -40; which then becomes 216 preserving the bit pattern representation of -40. That is what everyone except ARM64 is doing - Windows, iOS, Mac. That is the behavior (may be undefined, is it?) I have to come to expect when casting signed/unsigned.
– Amit
Mar 8 at 4:36
what compiler and version?
– old_timer
Mar 8 at 4:41
so.c:5:12: warning: overflow in conversion from ‘double’ to ‘unsigned char’ changes value from ‘-4.0159999999999997e+1’ to ‘0’ [-Woverflow]
– old_timer
Mar 8 at 4:44
Visual Studio 2017 ARM64 compiler targeting Windows machines.
– Amit
Mar 8 at 4:45
|
show 2 more comments
1
What value do you expect to see?
– Mark Ransom
Mar 8 at 4:29
Well 216; -40.16 first become -40; which then becomes 216 preserving the bit pattern representation of -40. That is what everyone except ARM64 is doing - Windows, iOS, Mac. That is the behavior (may be undefined, is it?) I have to come to expect when casting signed/unsigned.
– Amit
Mar 8 at 4:36
what compiler and version?
– old_timer
Mar 8 at 4:41
so.c:5:12: warning: overflow in conversion from ‘double’ to ‘unsigned char’ changes value from ‘-4.0159999999999997e+1’ to ‘0’ [-Woverflow]
– old_timer
Mar 8 at 4:44
Visual Studio 2017 ARM64 compiler targeting Windows machines.
– Amit
Mar 8 at 4:45
1
1
What value do you expect to see?
– Mark Ransom
Mar 8 at 4:29
What value do you expect to see?
– Mark Ransom
Mar 8 at 4:29
Well 216; -40.16 first become -40; which then becomes 216 preserving the bit pattern representation of -40. That is what everyone except ARM64 is doing - Windows, iOS, Mac. That is the behavior (may be undefined, is it?) I have to come to expect when casting signed/unsigned.
– Amit
Mar 8 at 4:36
Well 216; -40.16 first become -40; which then becomes 216 preserving the bit pattern representation of -40. That is what everyone except ARM64 is doing - Windows, iOS, Mac. That is the behavior (may be undefined, is it?) I have to come to expect when casting signed/unsigned.
– Amit
Mar 8 at 4:36
what compiler and version?
– old_timer
Mar 8 at 4:41
what compiler and version?
– old_timer
Mar 8 at 4:41
so.c:5:12: warning: overflow in conversion from ‘double’ to ‘unsigned char’ changes value from ‘-4.0159999999999997e+1’ to ‘0’ [-Woverflow]
– old_timer
Mar 8 at 4:44
so.c:5:12: warning: overflow in conversion from ‘double’ to ‘unsigned char’ changes value from ‘-4.0159999999999997e+1’ to ‘0’ [-Woverflow]
– old_timer
Mar 8 at 4:44
Visual Studio 2017 ARM64 compiler targeting Windows machines.
– Amit
Mar 8 at 4:45
Visual Studio 2017 ARM64 compiler targeting Windows machines.
– Amit
Mar 8 at 4:45
|
show 2 more comments
1 Answer
1
active
oldest
votes
What the C standard says (and there's similar text in the C++ one):
When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the
value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is undefined.
So, getting 216 out of -40.16 with a single cast from double
to unsigned char
is already UB. In fact, getting any result in this case is UB. Which is why the compiler is free to produce anything and not 216 that you desire.
You may want to do two casts:
(unsigned char)(int)-40.16
Again, the first cast (to int) is still subject to the above restriction I quoted.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55056714%2fsigned-double-to-unsigned-byte-arm64-versus-win64%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
What the C standard says (and there's similar text in the C++ one):
When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the
value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is undefined.
So, getting 216 out of -40.16 with a single cast from double
to unsigned char
is already UB. In fact, getting any result in this case is UB. Which is why the compiler is free to produce anything and not 216 that you desire.
You may want to do two casts:
(unsigned char)(int)-40.16
Again, the first cast (to int) is still subject to the above restriction I quoted.
add a comment |
What the C standard says (and there's similar text in the C++ one):
When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the
value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is undefined.
So, getting 216 out of -40.16 with a single cast from double
to unsigned char
is already UB. In fact, getting any result in this case is UB. Which is why the compiler is free to produce anything and not 216 that you desire.
You may want to do two casts:
(unsigned char)(int)-40.16
Again, the first cast (to int) is still subject to the above restriction I quoted.
add a comment |
What the C standard says (and there's similar text in the C++ one):
When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the
value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is undefined.
So, getting 216 out of -40.16 with a single cast from double
to unsigned char
is already UB. In fact, getting any result in this case is UB. Which is why the compiler is free to produce anything and not 216 that you desire.
You may want to do two casts:
(unsigned char)(int)-40.16
Again, the first cast (to int) is still subject to the above restriction I quoted.
What the C standard says (and there's similar text in the C++ one):
When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the
value is truncated toward zero). If the value of the integral part
cannot be represented by the integer type, the behavior is undefined.
So, getting 216 out of -40.16 with a single cast from double
to unsigned char
is already UB. In fact, getting any result in this case is UB. Which is why the compiler is free to produce anything and not 216 that you desire.
You may want to do two casts:
(unsigned char)(int)-40.16
Again, the first cast (to int) is still subject to the above restriction I quoted.
answered Mar 8 at 5:27
Alexey FrunzeAlexey Frunze
52.7k953129
52.7k953129
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55056714%2fsigned-double-to-unsigned-byte-arm64-versus-win64%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
What value do you expect to see?
– Mark Ransom
Mar 8 at 4:29
Well 216; -40.16 first become -40; which then becomes 216 preserving the bit pattern representation of -40. That is what everyone except ARM64 is doing - Windows, iOS, Mac. That is the behavior (may be undefined, is it?) I have to come to expect when casting signed/unsigned.
– Amit
Mar 8 at 4:36
what compiler and version?
– old_timer
Mar 8 at 4:41
so.c:5:12: warning: overflow in conversion from ‘double’ to ‘unsigned char’ changes value from ‘-4.0159999999999997e+1’ to ‘0’ [-Woverflow]
– old_timer
Mar 8 at 4:44
Visual Studio 2017 ARM64 compiler targeting Windows machines.
– Amit
Mar 8 at 4:45