0

I've tried everything to figure this out and I don't get what I'm doing wrong. converting to signed makes everything past the numerical hex values and I know if I have an integer I can straight up use "ULL" to convert it and bitshift away but I can't figure out

basically

void   tick(unsigned long* tmp) { //input as a parameter
   signed long temp = tmp;

   printf("%x\n", temp >> 16 & 0xff);

   tmp = (signed) temp;

   return;
}

EDIT: so I'm stupid and I should've used %lu not %x, now I can see my results but I don't see any change occurring with clock, even with bitshifting the temp

Tezirg
  • 1,629
  • 1
  • 10
  • 20
  • 4
    First, the initialization `signed long temp = tmp` is very suspect. Secondly, for some specified input, what is the expected and actual output? And please read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly learn how to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). – Some programmer dude Nov 01 '18 at 07:28
  • 2
    This isn't even valid C and will not compile cleanly. – Lundin Nov 01 '18 at 07:30
  • 2
    Why are you mixing pointers and non pointers, do you mean `signed long temp = (signed long)*tmp;`?, if you want to work whit the address of `tmp` use `intptr_t` instead of `long` – David Ranieri Nov 01 '18 at 07:33
  • Why are you converting to signed, then? – rici Nov 01 '18 at 07:50
  • THe question is not so much of what you're doing wrong, but rather what are you trying to achieve? – Jabberwocky Nov 01 '18 at 08:26
  • and temp is not an int so it can't be printed with `%x`[ – phuclv Nov 01 '18 at 09:33
  • I must've not stated everything properly, I apologize. The goal is to add one byte to the temp variable in a clock format. So the temp variable is laid out like so: 0x(hour)(minute)(second)(am/pm) with 2 bytes for each parameter. I need to add one "second" to the long parameter but I'm struggling in converting the unsigned long into a long to modify in the first place (I'll update my question as well) – Jacinth Gudetti Nov 01 '18 at 10:32
  • I'm new to C, I see the problem with %x, I should've used %lu – Jacinth Gudetti Nov 01 '18 at 10:37

2 Answers2

0
  • The function parameter is a pointer, so you need to dereference it to access it's value.
  • You need to assign the bitshifted value to your variable if you want to store it.
  • And if you want the value to be changed under the pointer, you need to assign the new value to the derefenced pointer
  • You also need to use long formating options for it to display correctly. (Here, lux -> long unsigned hexadecimal)

Here is a modified version:

#include <stdio.h>

void    tick(unsigned long* input)
{
  unsigned long temp;

  temp = ((*input) >> 16) & 0xff;
  printf("%lux\n", temp);

  *input = temp;
}

int main()
{
  long test = 1;
  tick(&test);
  test = 0b100000000000000000;
  tick(&test);
  test = 0b111111111111111111;
  tick(&test);
}
Tezirg
  • 1,629
  • 1
  • 10
  • 20
0

From information in the comments, you actually have your integer laid out like with hour/minute/seconds/am-pm with 2 bytes(make sure you meant 2 bytes, and not 2 nibbles) for each field like e.g. this:

+--+--+--+--+--+--+--+--+
|H |H |M |M |S |S |AM PM|
+--+--+--+--+--+--+--+--+

And you want to extract the 2 bytes containing the seconds and add 1 to them.

You'll need 8 bytes (64 bits) to represent that value, so I'll use the uint64_t type instead of an unsigned long for that, you get the uint64_t type by #include <stdint.h>

void tick(uint64_t *value) { //input as a parameter
  //extract seconds 
  unsigned int seconds ((*value) >> 16) & 0xffff

  printf("seconds = %u\n", seconds);

 //add 1 second and pack the value back:
 seconds += 1;
 *value = (value & 0xffffffff0000ffff) | ((seconds & 0xffff) << 16);

 return; //returns void
}

(Now, you might also need to handle wrapping, e.g. increase the minute when seconds reach 60 and so on)

nos
  • 223,662
  • 58
  • 417
  • 506
  • I need to use unsigned long unfortunately, can I convert to a uint64_t? – Jacinth Gudetti Nov 01 '18 at 19:44
  • If you know that unsigned long on your platform is 64 bit, just use unsigned long instead of uint64_t. But be sure that you really meant that each field (such as a second) is 16 bits (2 bytes) and not 8 bit (1 byte). – nos Nov 01 '18 at 20:37