I am doing some calculations that require me to use long long but the output is not correct.
This works:
int32_t total = 10; //can be anything between 10 and -10. Stored as int32_t because of previous calculations
int32_t compensation = total * 10000;
Serial.printf("compensation: %d. total: %d. PCSCALEVAL: %d\r\n", compensation, total, 10000);
#define PCSCALEVAL 100000000
int32_t total = 10; //can be anything between 10 and -10. Stored as int32_t because of previous calculations
long long compensation = total * PCSCALEVAL;
Serial.printf("compensation: %ld. total: %d. PCSCALEVAL: %d\r\n", compensation, total, PCSCALEVAL);
Is there a certain reason why you are using a ‘long long’ type instead of ‘int32_t’? As the photon’s processor does not exceed 32bits we should expect undefined behaviour when using types meant for 64bit systems should we not?
I was wrong about the range of my total variable and it can actually go between -99 and 99, this will be multiplied by PCSCALEVAL so I need to be able to use numbers between -9900000000 and 9900000000. These will not fit in the int32_t data type.
Is there an easy way to use large numbers by splitting them up or should I accept a loss in resolution by reducing the size of PCSCALEVAL by a factor of 10.
@joe4465, you could do your calculations with float or double and convert back to integer when necessary. Is there any reason you need do to everything with integers?
Are you actually loosing information content (as in theory of information) or are you just assuming reduced resolution?
Just because you get a result with many digits, it does not necessarily mean that it is more accurate than one with less (theory of mathematical significance)
@ScruffR the pixelIndex is 0 - 1024 and the value _pixC can be anywhere from 3E+6 to 7E+8.
The manufacturer told me reducing PCSCALEVAL would reduce resolution but I’m not sure whether reducing by a factor of 10 would really have any noticable difference. This also has a knock on affect on the formula used to calculate pixC which is the sensitivity coefficients for each pixel.
Im guessing one possibility would be to define a structure/bitfield with multiple fields which together represent your large number. Then add getters/setters and overload the operators with corresponding assembly code which correctly adds/subtracts/… a numerical parameter from the structure’s fields. Factorization should however usually be enough for simpler applications.
Yes, it’s supported by the compiler. Similar to how it is on the Arduino Uno, even thought the MCU is only 8-bit, the compiler supports 32/64 bit operations in software.
Here, the MCU is 32-bit, and the compiler provides 64-bit operations in software.
The trap is that not all C runtime functions are equipped to deal with 64-bits, sprintf being one example.
Update:
Nevermind, my own stupidity
I should have written
ll = (uint64_t)1 << b;
I should know better
Outdated original post (code corrected tho’):
Sorry @mdma for resurrecting this thread, but in connection with another question I came up with this test code that does suggest that uint64_t (aka unsigned long long) is not fully supported - or I’m missing something
uint64_t ll = 0;
void setup()
{
pinMode(D7, OUTPUT);
Particle.function("shift", doShift);
}
void loop()
{
digitalWrite(D7, ll ? HIGH : LOW);
}
int doShift(String bits)
{
int b = bits.toInt();
// ll = 1 << b; // <-- mistake: 1 is an int so it's an int shift
// this works as expected
ll = (uint64_t)1 << b;
return b;
}
I tried to avoid involving any “function” in the 64bit operations but only basic C operations and operators.
Hence the otherwise superfluous ternary operator to explicitly pass HIGH/LOW.
Once I pass any bit number greater than 31 the LED goes off.
How come, if 64bit is supported and how would we know what works and what not if not even this one works?
Great thread here. I’m noticing it hasn’t moved since the middle of last year. Has anyone had success with an alternative approach? I’ve got some decoding to do on a custom EAN13 barcode which is 13 decimal digits long (essentially a 40-bit number) that requires some bit-bashing operations to extract fields from within the barcode. It comes in from the reader as an ASCII string, but I need to convert it to an integer representation to work on it.
@ScruffR, your last post was a little confusing. Were you implying that the code works after you cast the 1 to a uint64_t?
Just a little unclear, and I don’t want to go on another red-bull-fueled coding session only to discover my approach is dead broken.