2

Given an unsigned char *x, I need to round the address that *x points to down to a multiple of 16. Such as 0x7fff5fbff7fc down to 0x7fff5fbff7f0. I've tried to shift it using:

x >> 4;
x << 4;

Also tried

x >>= 4;
x <<= 4;

but it won't allow me to do this considering it is not an integer. Any advice?

HamZa
  • 14,671
  • 11
  • 54
  • 75
David Scheibe
  • 63
  • 1
  • 6
  • 1
    (as in `(char *)((uintptr_t)(x) & ~(uintptr_t)(15))`...) –  Oct 20 '13 at 18:26
  • Im getting undeclared identifier uintptr_t – David Scheibe Oct 20 '13 at 18:31
  • By the way, your `x >>= 4; x <<= 4;` approach would have worked if you had introduced a temporary variable of type `uintptr_t`. –  Oct 20 '13 at 18:31
  • @davidS You have to import a certain header file to access that type. IIRC it's `` but it's trivial to google it. –  Oct 20 '13 at 18:32
  • I'm not sure if I am allowed to add any headers for this program. The goal of it is to make it a multiple of 16 so i can print out 0x7fff5fbff7f0 then 0x7fff5fbff00 then 0x7fff5fbff81 etc, – David Scheibe Oct 20 '13 at 18:37
  • @davidS "I'm not sure if I am allowed to add any headers for this program." - ***???*** –  Oct 20 '13 at 18:38
  • I mean that if there is any way for me to accomplish rounding down to 16, without including other headers, then that would be most helpful. – David Scheibe Oct 20 '13 at 18:40
  • @davidS You certainly **do want** to use `uintptr_t` since it's guaranteed to be able to hold a pointer without loss of data when performing type conversions. If you don't want to include a header file (I still don't understand why that is such a big problem), you can just go ahead, search for the definition of `uintptr_t` in `` and use that type directly, but your code isn't going to be portable if you take that approach. –  Oct 20 '13 at 18:43
  • @H2CO3 if this is a class question, portability isn't a concern. – Alexander Oh Oct 20 '13 at 18:51
  • Okay. so to make sure i understand your code correctly. (char *)((uintptr_t)(x) converts x to a uintptr_t. and ~(uintptr_t)(15) converts 0x0000..0F to 0xfffff..f0. then I use & on the 2 of them to simply change the last hexidecimal of x to a 0? – David Scheibe Oct 20 '13 at 18:53
  • @Alex This doesn't seem like a typical assignment question, though. –  Oct 20 '13 at 18:53
  • @davidS Yes, that's exactly how it works. –  Oct 20 '13 at 18:54

2 Answers2

7
(unsigned char *)((uintptr_t)(x) & ~(uintptr_t)(15))

if you want to be portable...

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • 1
    Some explanation please :) – HamZa Oct 20 '13 at 18:35
  • @HamZa `~(uintptr_t)15` is the bitwise negated of 15, i. e. `0xffff...fff0` (it's an `uintptr_t` so that it's exactly as long as a pointer). If you bitwise AND the pointer with it, you round it down to 16s. –  Oct 20 '13 at 18:37
0

try x & 0xfffffff0 at least for 32 bit integers.

Alexander Oh
  • 24,223
  • 14
  • 73
  • 76
  • 3
    This will fail miserably on non-32-bit implementations. It isn't obliged to compile without casts to an integer either. –  Oct 20 '13 at 18:27