Create a 64-bit result using different values
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have to create a 64byte value using val1
, val2
, val3
and val4
.
Output should look like: 0xabcdabcd01000000
, but I am getting 0x81000000
uint32_t val1 = 0xabcdabcd;
uint8_t val2 = 1;
uint8_t val3 = 0;
uint16_t val4 = 0;
uint8_t final_val[8];
#define ADDR (&final_val[0])
//The output format is as follows: NNNNNNNNxyz
// NNNNNNNN: value1 in hex
// x - val2,
// y - val3,
// z - val4
int main()
uint64_t *ptr = (uint64_t *)ADDR ;
*ptr = val1<<31
c
|
show 2 more comments
I have to create a 64byte value using val1
, val2
, val3
and val4
.
Output should look like: 0xabcdabcd01000000
, but I am getting 0x81000000
uint32_t val1 = 0xabcdabcd;
uint8_t val2 = 1;
uint8_t val3 = 0;
uint16_t val4 = 0;
uint8_t final_val[8];
#define ADDR (&final_val[0])
//The output format is as follows: NNNNNNNNxyz
// NNNNNNNN: value1 in hex
// x - val2,
// y - val3,
// z - val4
int main()
uint64_t *ptr = (uint64_t *)ADDR ;
*ptr = val1<<31
c
Where isfinal_val
declared? please provide the minimum code to reproduce
– PC Luddite
Nov 13 '18 at 22:06
3
I think you refer to 64 bit value instead of 64 bytes.
– Patrik Valkovič
Nov 13 '18 at 22:06
1
Does casting val1/2/3/4 to uint64_t before shifting do the trick?
– Ctx
Nov 13 '18 at 22:07
3
You've got a strict-aliasing violation when you dereference a pointer tofinal_val[0]
as auint64_t
.
– Christian Gibbons
Nov 13 '18 at 22:09
1
uint64_t *ptr =... printf("%p 0x%x n",ptr,*ptr);
implies your compiler is not helping you with good warnings. Enable all warnings or get a new compiler.
– chux
Nov 13 '18 at 22:15
|
show 2 more comments
I have to create a 64byte value using val1
, val2
, val3
and val4
.
Output should look like: 0xabcdabcd01000000
, but I am getting 0x81000000
uint32_t val1 = 0xabcdabcd;
uint8_t val2 = 1;
uint8_t val3 = 0;
uint16_t val4 = 0;
uint8_t final_val[8];
#define ADDR (&final_val[0])
//The output format is as follows: NNNNNNNNxyz
// NNNNNNNN: value1 in hex
// x - val2,
// y - val3,
// z - val4
int main()
uint64_t *ptr = (uint64_t *)ADDR ;
*ptr = val1<<31
c
I have to create a 64byte value using val1
, val2
, val3
and val4
.
Output should look like: 0xabcdabcd01000000
, but I am getting 0x81000000
uint32_t val1 = 0xabcdabcd;
uint8_t val2 = 1;
uint8_t val3 = 0;
uint16_t val4 = 0;
uint8_t final_val[8];
#define ADDR (&final_val[0])
//The output format is as follows: NNNNNNNNxyz
// NNNNNNNN: value1 in hex
// x - val2,
// y - val3,
// z - val4
int main()
uint64_t *ptr = (uint64_t *)ADDR ;
*ptr = val1<<31
c
c
edited Nov 13 '18 at 22:20
Jonathan Leffler
574k956881041
574k956881041
asked Nov 13 '18 at 22:04
user968000user968000
88611524
88611524
Where isfinal_val
declared? please provide the minimum code to reproduce
– PC Luddite
Nov 13 '18 at 22:06
3
I think you refer to 64 bit value instead of 64 bytes.
– Patrik Valkovič
Nov 13 '18 at 22:06
1
Does casting val1/2/3/4 to uint64_t before shifting do the trick?
– Ctx
Nov 13 '18 at 22:07
3
You've got a strict-aliasing violation when you dereference a pointer tofinal_val[0]
as auint64_t
.
– Christian Gibbons
Nov 13 '18 at 22:09
1
uint64_t *ptr =... printf("%p 0x%x n",ptr,*ptr);
implies your compiler is not helping you with good warnings. Enable all warnings or get a new compiler.
– chux
Nov 13 '18 at 22:15
|
show 2 more comments
Where isfinal_val
declared? please provide the minimum code to reproduce
– PC Luddite
Nov 13 '18 at 22:06
3
I think you refer to 64 bit value instead of 64 bytes.
– Patrik Valkovič
Nov 13 '18 at 22:06
1
Does casting val1/2/3/4 to uint64_t before shifting do the trick?
– Ctx
Nov 13 '18 at 22:07
3
You've got a strict-aliasing violation when you dereference a pointer tofinal_val[0]
as auint64_t
.
– Christian Gibbons
Nov 13 '18 at 22:09
1
uint64_t *ptr =... printf("%p 0x%x n",ptr,*ptr);
implies your compiler is not helping you with good warnings. Enable all warnings or get a new compiler.
– chux
Nov 13 '18 at 22:15
Where is
final_val
declared? please provide the minimum code to reproduce– PC Luddite
Nov 13 '18 at 22:06
Where is
final_val
declared? please provide the minimum code to reproduce– PC Luddite
Nov 13 '18 at 22:06
3
3
I think you refer to 64 bit value instead of 64 bytes.
– Patrik Valkovič
Nov 13 '18 at 22:06
I think you refer to 64 bit value instead of 64 bytes.
– Patrik Valkovič
Nov 13 '18 at 22:06
1
1
Does casting val1/2/3/4 to uint64_t before shifting do the trick?
– Ctx
Nov 13 '18 at 22:07
Does casting val1/2/3/4 to uint64_t before shifting do the trick?
– Ctx
Nov 13 '18 at 22:07
3
3
You've got a strict-aliasing violation when you dereference a pointer to
final_val[0]
as a uint64_t
.– Christian Gibbons
Nov 13 '18 at 22:09
You've got a strict-aliasing violation when you dereference a pointer to
final_val[0]
as a uint64_t
.– Christian Gibbons
Nov 13 '18 at 22:09
1
1
uint64_t *ptr =... printf("%p 0x%x n",ptr,*ptr);
implies your compiler is not helping you with good warnings. Enable all warnings or get a new compiler.– chux
Nov 13 '18 at 22:15
uint64_t *ptr =... printf("%p 0x%x n",ptr,*ptr);
implies your compiler is not helping you with good warnings. Enable all warnings or get a new compiler.– chux
Nov 13 '18 at 22:15
|
show 2 more comments
2 Answers
2
active
oldest
votes
Each of the shift terms except the first is evaluated as an int
; the first is evaluated as a uint32_t
which is probably an unsigned int
. These results are then or'd together in a uint32_t
, and then assigned to your 64-bit result.
You need at least the first shift performed as a 64-bit calculation:
*ptr = (uint64_t)val1 << 32 | val2 << 24 | val3 << 16 | val4;
This can shift by 32 (as required, instead of 31 as before) because the shift is smaller than the size of the operand (uint64_t
). Previously, you couldn't use 32 because you'd be told the shift is too big.
You might prefer the symmetry of:
*ptr = (uint64_t)val1 << 32 | (uint64_t)val2 << 24 | (uint64_t)val3 << 16 | (uint64_t)val4;
Your printing is also faulty. You should be using the macros from <inttypes.h>
to specify the format for the uint64_t
value:
printf("%p 0x%" PRIx64 "n", ptr, *ptr);
Note that if you used unsigned long long *ptr
etc, you'd use 0x%llx
.
The use of final_val
is also dubious at best; it could crash on some machine types if final_val
is not appropriately aligned for a 64-bit type (not aligned on a 64-bit boundary). In the code shown, you should simply use a uint64_t
variable to be the target of the pointer (since the code shown doesn't use final_val
otherwise). If you did need to use the array of uint8_t
values for some reason, then there are better ways to load the data. You'd get different results on little-endian vs big-endian machines, too.
For a complete answer, please add a note thatuint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just dropptr
in favour for anuint64_t
. And we really shouldn't shift onint
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.
– Lundin
Nov 14 '18 at 10:26
add a comment |
To create a 64-bit value:
1) Insure shifts are done with 64-bit operands when the result exceeds 32 bits.
val1<<31
(uint64_t) val1 << 31
2) Shift 32, not 31 bits to achieve the goal of NNNNNNNNxyz
3) Avoid pointers tricks.
uint8_t final_val[8];
// uint64_t *ptr = (uint64_t *)ADDR ;
uint64_t u64 = (uint64_t) val1 << 32 | val2 << 24 | val3 <<16 | val4;
memcpy(final_val, &u64, sizeof final_val);
4) Use matching printf specifiers.
#include <inttypes.h>
// v---- Not x, x is for unsigned
// printf("0x%xn", u64);
printf("0x%" PRIx64 "n", u64);
// ^----^ from inttypes.h
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%2f53290205%2fcreate-a-64-bit-result-using-different-values%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Each of the shift terms except the first is evaluated as an int
; the first is evaluated as a uint32_t
which is probably an unsigned int
. These results are then or'd together in a uint32_t
, and then assigned to your 64-bit result.
You need at least the first shift performed as a 64-bit calculation:
*ptr = (uint64_t)val1 << 32 | val2 << 24 | val3 << 16 | val4;
This can shift by 32 (as required, instead of 31 as before) because the shift is smaller than the size of the operand (uint64_t
). Previously, you couldn't use 32 because you'd be told the shift is too big.
You might prefer the symmetry of:
*ptr = (uint64_t)val1 << 32 | (uint64_t)val2 << 24 | (uint64_t)val3 << 16 | (uint64_t)val4;
Your printing is also faulty. You should be using the macros from <inttypes.h>
to specify the format for the uint64_t
value:
printf("%p 0x%" PRIx64 "n", ptr, *ptr);
Note that if you used unsigned long long *ptr
etc, you'd use 0x%llx
.
The use of final_val
is also dubious at best; it could crash on some machine types if final_val
is not appropriately aligned for a 64-bit type (not aligned on a 64-bit boundary). In the code shown, you should simply use a uint64_t
variable to be the target of the pointer (since the code shown doesn't use final_val
otherwise). If you did need to use the array of uint8_t
values for some reason, then there are better ways to load the data. You'd get different results on little-endian vs big-endian machines, too.
For a complete answer, please add a note thatuint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just dropptr
in favour for anuint64_t
. And we really shouldn't shift onint
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.
– Lundin
Nov 14 '18 at 10:26
add a comment |
Each of the shift terms except the first is evaluated as an int
; the first is evaluated as a uint32_t
which is probably an unsigned int
. These results are then or'd together in a uint32_t
, and then assigned to your 64-bit result.
You need at least the first shift performed as a 64-bit calculation:
*ptr = (uint64_t)val1 << 32 | val2 << 24 | val3 << 16 | val4;
This can shift by 32 (as required, instead of 31 as before) because the shift is smaller than the size of the operand (uint64_t
). Previously, you couldn't use 32 because you'd be told the shift is too big.
You might prefer the symmetry of:
*ptr = (uint64_t)val1 << 32 | (uint64_t)val2 << 24 | (uint64_t)val3 << 16 | (uint64_t)val4;
Your printing is also faulty. You should be using the macros from <inttypes.h>
to specify the format for the uint64_t
value:
printf("%p 0x%" PRIx64 "n", ptr, *ptr);
Note that if you used unsigned long long *ptr
etc, you'd use 0x%llx
.
The use of final_val
is also dubious at best; it could crash on some machine types if final_val
is not appropriately aligned for a 64-bit type (not aligned on a 64-bit boundary). In the code shown, you should simply use a uint64_t
variable to be the target of the pointer (since the code shown doesn't use final_val
otherwise). If you did need to use the array of uint8_t
values for some reason, then there are better ways to load the data. You'd get different results on little-endian vs big-endian machines, too.
For a complete answer, please add a note thatuint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just dropptr
in favour for anuint64_t
. And we really shouldn't shift onint
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.
– Lundin
Nov 14 '18 at 10:26
add a comment |
Each of the shift terms except the first is evaluated as an int
; the first is evaluated as a uint32_t
which is probably an unsigned int
. These results are then or'd together in a uint32_t
, and then assigned to your 64-bit result.
You need at least the first shift performed as a 64-bit calculation:
*ptr = (uint64_t)val1 << 32 | val2 << 24 | val3 << 16 | val4;
This can shift by 32 (as required, instead of 31 as before) because the shift is smaller than the size of the operand (uint64_t
). Previously, you couldn't use 32 because you'd be told the shift is too big.
You might prefer the symmetry of:
*ptr = (uint64_t)val1 << 32 | (uint64_t)val2 << 24 | (uint64_t)val3 << 16 | (uint64_t)val4;
Your printing is also faulty. You should be using the macros from <inttypes.h>
to specify the format for the uint64_t
value:
printf("%p 0x%" PRIx64 "n", ptr, *ptr);
Note that if you used unsigned long long *ptr
etc, you'd use 0x%llx
.
The use of final_val
is also dubious at best; it could crash on some machine types if final_val
is not appropriately aligned for a 64-bit type (not aligned on a 64-bit boundary). In the code shown, you should simply use a uint64_t
variable to be the target of the pointer (since the code shown doesn't use final_val
otherwise). If you did need to use the array of uint8_t
values for some reason, then there are better ways to load the data. You'd get different results on little-endian vs big-endian machines, too.
Each of the shift terms except the first is evaluated as an int
; the first is evaluated as a uint32_t
which is probably an unsigned int
. These results are then or'd together in a uint32_t
, and then assigned to your 64-bit result.
You need at least the first shift performed as a 64-bit calculation:
*ptr = (uint64_t)val1 << 32 | val2 << 24 | val3 << 16 | val4;
This can shift by 32 (as required, instead of 31 as before) because the shift is smaller than the size of the operand (uint64_t
). Previously, you couldn't use 32 because you'd be told the shift is too big.
You might prefer the symmetry of:
*ptr = (uint64_t)val1 << 32 | (uint64_t)val2 << 24 | (uint64_t)val3 << 16 | (uint64_t)val4;
Your printing is also faulty. You should be using the macros from <inttypes.h>
to specify the format for the uint64_t
value:
printf("%p 0x%" PRIx64 "n", ptr, *ptr);
Note that if you used unsigned long long *ptr
etc, you'd use 0x%llx
.
The use of final_val
is also dubious at best; it could crash on some machine types if final_val
is not appropriately aligned for a 64-bit type (not aligned on a 64-bit boundary). In the code shown, you should simply use a uint64_t
variable to be the target of the pointer (since the code shown doesn't use final_val
otherwise). If you did need to use the array of uint8_t
values for some reason, then there are better ways to load the data. You'd get different results on little-endian vs big-endian machines, too.
edited Nov 13 '18 at 22:31
answered Nov 13 '18 at 22:17
Jonathan LefflerJonathan Leffler
574k956881041
574k956881041
For a complete answer, please add a note thatuint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just dropptr
in favour for anuint64_t
. And we really shouldn't shift onint
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.
– Lundin
Nov 14 '18 at 10:26
add a comment |
For a complete answer, please add a note thatuint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just dropptr
in favour for anuint64_t
. And we really shouldn't shift onint
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.
– Lundin
Nov 14 '18 at 10:26
For a complete answer, please add a note that
uint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just drop ptr
in favour for an uint64_t
. And we really shouldn't shift on int
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.– Lundin
Nov 14 '18 at 10:26
For a complete answer, please add a note that
uint64_t *ptr = (uint64_t *)ADDR ;
is a strict aliasing violation and UB, or alternatively just drop ptr
in favour for an uint64_t
. And we really shouldn't shift on int
or other signed types, ever. So the version with explicit casts on all operands is always to prefer.– Lundin
Nov 14 '18 at 10:26
add a comment |
To create a 64-bit value:
1) Insure shifts are done with 64-bit operands when the result exceeds 32 bits.
val1<<31
(uint64_t) val1 << 31
2) Shift 32, not 31 bits to achieve the goal of NNNNNNNNxyz
3) Avoid pointers tricks.
uint8_t final_val[8];
// uint64_t *ptr = (uint64_t *)ADDR ;
uint64_t u64 = (uint64_t) val1 << 32 | val2 << 24 | val3 <<16 | val4;
memcpy(final_val, &u64, sizeof final_val);
4) Use matching printf specifiers.
#include <inttypes.h>
// v---- Not x, x is for unsigned
// printf("0x%xn", u64);
printf("0x%" PRIx64 "n", u64);
// ^----^ from inttypes.h
add a comment |
To create a 64-bit value:
1) Insure shifts are done with 64-bit operands when the result exceeds 32 bits.
val1<<31
(uint64_t) val1 << 31
2) Shift 32, not 31 bits to achieve the goal of NNNNNNNNxyz
3) Avoid pointers tricks.
uint8_t final_val[8];
// uint64_t *ptr = (uint64_t *)ADDR ;
uint64_t u64 = (uint64_t) val1 << 32 | val2 << 24 | val3 <<16 | val4;
memcpy(final_val, &u64, sizeof final_val);
4) Use matching printf specifiers.
#include <inttypes.h>
// v---- Not x, x is for unsigned
// printf("0x%xn", u64);
printf("0x%" PRIx64 "n", u64);
// ^----^ from inttypes.h
add a comment |
To create a 64-bit value:
1) Insure shifts are done with 64-bit operands when the result exceeds 32 bits.
val1<<31
(uint64_t) val1 << 31
2) Shift 32, not 31 bits to achieve the goal of NNNNNNNNxyz
3) Avoid pointers tricks.
uint8_t final_val[8];
// uint64_t *ptr = (uint64_t *)ADDR ;
uint64_t u64 = (uint64_t) val1 << 32 | val2 << 24 | val3 <<16 | val4;
memcpy(final_val, &u64, sizeof final_val);
4) Use matching printf specifiers.
#include <inttypes.h>
// v---- Not x, x is for unsigned
// printf("0x%xn", u64);
printf("0x%" PRIx64 "n", u64);
// ^----^ from inttypes.h
To create a 64-bit value:
1) Insure shifts are done with 64-bit operands when the result exceeds 32 bits.
val1<<31
(uint64_t) val1 << 31
2) Shift 32, not 31 bits to achieve the goal of NNNNNNNNxyz
3) Avoid pointers tricks.
uint8_t final_val[8];
// uint64_t *ptr = (uint64_t *)ADDR ;
uint64_t u64 = (uint64_t) val1 << 32 | val2 << 24 | val3 <<16 | val4;
memcpy(final_val, &u64, sizeof final_val);
4) Use matching printf specifiers.
#include <inttypes.h>
// v---- Not x, x is for unsigned
// printf("0x%xn", u64);
printf("0x%" PRIx64 "n", u64);
// ^----^ from inttypes.h
edited Nov 13 '18 at 22:28
answered Nov 13 '18 at 22:22
chuxchux
85k874157
85k874157
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%2f53290205%2fcreate-a-64-bit-result-using-different-values%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
Where is
final_val
declared? please provide the minimum code to reproduce– PC Luddite
Nov 13 '18 at 22:06
3
I think you refer to 64 bit value instead of 64 bytes.
– Patrik Valkovič
Nov 13 '18 at 22:06
1
Does casting val1/2/3/4 to uint64_t before shifting do the trick?
– Ctx
Nov 13 '18 at 22:07
3
You've got a strict-aliasing violation when you dereference a pointer to
final_val[0]
as auint64_t
.– Christian Gibbons
Nov 13 '18 at 22:09
1
uint64_t *ptr =... printf("%p 0x%x n",ptr,*ptr);
implies your compiler is not helping you with good warnings. Enable all warnings or get a new compiler.– chux
Nov 13 '18 at 22:15