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;








0















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;









share|improve this question



















  • 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

















0















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;









share|improve this question



















  • 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













0












0








0








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;









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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












  • 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












1 Answer
1






active

oldest

votes


















4














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.






share|improve this answer























    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
    );



    );













    draft saved

    draft discarded


















    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









    4














    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.






    share|improve this answer



























      4














      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.






      share|improve this answer

























        4












        4








        4







        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.






        share|improve this answer













        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 8 at 5:27









        Alexey FrunzeAlexey Frunze

        52.7k953129




        52.7k953129





























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко