how to solve this equation?

Hi there,

I am calculating with datatypes unsigned int (0-65535).
The operation I want to resolve is unsigned int value= (1000/1023)*511;

I want to avoid using float variables.
Does someone know how I can solve this equation?
Is it maybe possible to solve it bitwise?

The decimal number of this calculation is irrelevant.

Thanks a lot for any tips!!

The value of the variable value will always be 0 because in integer math 1000/1023 is 0.

Not sure what you want, here.

If you're trying to find an integer representation of a fraction and multiply it by 511, do the multiplication first and then divide. So, while (1000/1023) * 511 will always equal zero, as was pointed out, (1000 * 511) / 1023 will equal 499.

DKWatson: (1000 * 511) / 1023 will equal 499.

That depends on which board you run that on. If the architecture has 32 bit ints then you're correct but on an AVR with a 16 bit int, it will not:

unsigned int value;

void setup()
{
  Serial.begin(9600);
  value = (1000 / 1023) * 511;
  Serial.print("1000/1023 = ");
  Serial.print(1000 / 1023);  // 0
  Serial.print("  so value = ");
  Serial.println(value);  // 0
  value = (1000 * 511) / 1023;
  Serial.print("1000*511 = ");
  Serial.print(1000 * 511);  // -13288
  Serial.print("  so value = ");
  Serial.println(value);  // 65524 
  value = (1000UL * 511) / 1023;
  Serial.print("1000UL*511 = ");
  Serial.print(1000UL * 511);  // 511000
  Serial.print("  so value = ");
  Serial.println(value);  // 499
}

void loop()
{

}

Ya, okay. Try (1000UL * 511) / 1023.

Thanks pert and DKWatson

That is what I was looking for.

I am just having an uncertainity what the "UL" causes- but google will help me :)

Thank you a lot!!!

When solving the right hand side of a statement, sufficient space is allocated temporarily, in registers or on the stack, to hold intermediate values of the calculation. In this particular case the largest value, 1023, will reside in an integer (2 bytes) so in my first comment, 1000 * 511 (which on a calculator would be 511,000) would get shoved into an integer slot and end up as mod 65536 or 7. By anointing any one of the values on the right hand side UL (unsigned long), 4 bytes are set aside for the calculation instead of 2.

DKWatson: Ya, okay. Try (1000UL * 511) / 1023.

Why are you changing the order of the operands? The OP has asked to evaluate his this expression (1000/1023)511 under **integer* number concept and not taking the floating point number concept. We need to convince him that the computer could only be used to solve our problems provided we remain obedient to the hard-cored rules based on which the computer works.

@GM dunno. My impression was that he was trying to use (1000/1023) to get a mapped fraction of 511 without using floats. In this example I was attempting to explain the order of operations and how (1000/1023) as an integer and always resolving to zero was not going to achieve his goal. So my effort was to instill the concept of remaining within the integer domain and coming up with a solution. If I am wrong, I sit corrected.

If we use paper-pencil, we can get 499.758. The OP is asking to find (499 and not 491 or 499.758) using computer and the associated programming language (the Arduino Platform).

We have these programming constructs - unsigned int data type, float data type, round

By hand calculation, we get 0.978 (against 1000/1023) which when multiplied by 511, the result is 499.758. As the OP does not want the fractional part of the result, the net result is: 499.

Now, I would like inquire of OP -- what programming language construct (function, method, data type, and etc.) we have that we can use to get 0.978 from 1000/1023. I see (for myself) that I have no other alternative except using the following codes:

float x = (1000/1023.0); //I have write 1023.0 and not 1023 in respect of float data type
Serial.println(x, 3);  //shows: 0.978

Now, getting the net result: 499

float x4 = x*511;
Serial.println((int)x4);   //shows: 499

I am just having an uncertainity what the "UL" causes- but google will help me

UL = Ugly Lizards.

Or, in the case of C++, unsigned long. The suffix tells the compiler to treat the value as an unsigned long instead of an int, when the actual value can be treated as an int. The reason that it matters is that 1000UL * 511 is performed using unsigned long registers, while 1000 * 511 is performed using int registers, which are not large enough to hold the result.

PaulS: [...]The reason that it matters is that 1000UL * 511 is performed using unsigned long registers, while 1000 * 511 is performed using int registers, which are not large enough to hold the result.

At the first reading, the term registers has taken me to the hardware register set of the 8-AVR/UNO which are 8-bit wide. Then, I have thought on int register and long register which I have mapped into 16-bit register and 32-bit register; these registers do not exist in the 8-bit AVR. If I would have seen like long buffer and int buffer, I would not be confused?

GolamMostafa: At the first reading, the term registers has taken me to the hardware register set of the 8-AVR/UNO which are 8-bit wide. Then, I have thought on int register and long register which I have mapped into 16-bit register and 32-bit register; these registers do not exist in the 8-bit AVR. If I would have seen like long buffer and int buffer, I would not be confused?

OK. So, my statement is a simplification of what actually happens. int multiplication uses multiple 8 bit registers (two per int). unsigned long multiplication also uses multiple 8 bit registers, but 4 per value.

The processor uses as many registers as it needs if they are available, if not it uses the stack. In fact by default, the registers are paired [16:17], [18:19], [20,21], [22,23] and [24,25]. When passing a byte to a function, the first register to get used is R24. Two bytes use R24 and R22 and so on. If the first argument is an integer, it will use R24 and R25 with the low order byte in R24. If it is a long, low order byte goes into R22 and so on. Again, the processor uses as many registers as it can (if available) as they are faster than the stack.

And yes, an alternative would have been to write,

unsigned int x = (1000./1023) * 511

without declaring x to be a float and would still get 499 as a result. The processor will allocate space for a float operation, but still assign the result as an integer. The difference here being that you needlessly incur the processing time of a float operation