Reverse calculation gives wrong result

In the code below i first calculate the number of steps a stepper should step according to the degrees value.

char     xDishBuffer[8]     = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

int      xGearRatio        =  42;          // stepper ratio per X degree of rotation (1:42)
int      xMicroSteps       =   2;          // Value of the microsteps
                                                         // Posible value's are 1, 2, 4, 8 and 16

typedef enum {
  X_ROTOR, Y_ROTOR
}
stepperfn;

long deg2step( float degrees, stepperfn stepper );
long deg2step( float degrees, stepperfn stepper ) {
  if (stepper == X_ROTOR)	return (( degrees / 1.8) * xMicroSteps * xGearRatio);
  if (stepper == Y_ROTOR)	return ((-degrees / 1.8) * yMicroSteps * yGearRatio);
}

long xResult = 0;
float xxResult ;

void setup() {
  Serial.begin(19200);                     // Start the Serial communication
  while (!Serial);

  xResult = deg2step(99.99, X_ROTOR);
  Serial.println(xResult);

  xxResult = xResult / xGearRatio / xMicroSteps * 1.8;
  dtostrf(xxResult, 7, 2, xDishBuffer);  // Make it alse printable
  Serial.println(xDishBuffer);
}

void loop() {
  // put your main code here, to run repeatedly:

}

With 99.99 degrees the result = 4666(.2) steps.
If i reverse the calculation the result should be almost equals 99.99 but printed is 99.00.

Maybe i use the wrong types but how to solve this?

Shouldn't xResult be a float ?

The results not wrong you are. The C language has been around since the 1970's and gcc the (compiler used by the IDE) has been around for many years - so any bugs which a newbie would find are long gone!

Converting (casting) to int allways rounds down.

Mark

UKHeliBob:
Shouldn't xResult be a float ?

No not according to the AccelStepper library documentation, it should be a long.
http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#ace236ede35f87c63d18da25810ec9736

holmes4:
The results not wrong you are. The C language has been around since the 1970's and gcc the (compiler used by the IDE) has been around for many years - so any bugs which a newbie would find are long gone!

Converting (casting) to int allways rounds down.

Mark

But where do i convert to a int?

xxResult = xResult / xGearRatio / xMicroSteps * 1.8;

xxResult = 4666 / 42 / 2 * 1.8; // int div int -> int
xxResult =111 / 2 * 1.8; // int div int -> int
xxResult =55 * 1.8; int mul float -> float
xxResult =99.00

voila

long xResult = 0; long is a type of int

..........
xxResult = xResult / xGearRatio / xMicroSteps * 1.8; // in here is the int cast, try
xxResult = (float)xResult / (float)xGearRatio /(float) xMicroSteps*1.8;

Logic - As I read the statement it read take xResult and / by GearRatio thats two ints so rounding down takes place. The same happens when you divide by xMicroSteps.

Mark

if you are doing some float calculation , and then converting to an integer type at the end ( or long ), it is often better to add 0.5 to the result before it gets truncated to an integer type.

This has the same effect as rounding the floating point number to the nearest integer number.

You need to be careful when mixing floating point types and integer types in calculation expressions.

You are also wasting a lot of time and probably memory by calculating (1/1.8)xmicrostepsxgearatio millions and millions of times when it doesn't change. Do you want to wear out your cpu ? Calculate this number once, in setup( ), or let the compiler do it.

The compiler might optimize it already...

gharryh:

UKHeliBob:
Shouldn't xResult be a float ?

No not according to the AccelStepper library documentation, it should be a long.
AccelStepper: AccelStepper Class Reference

Well, considering that the code you posted does not compile (yGearRatio and yMicroSteps not defined) and it does not use the AccelStepper library, I don't see the relevance of what AccelStepper wants.