Real maths

I need to do some maths but I’m having a issue…

The following lines would be acceptable in BASIC…

y=2012
m=2
d=13
h=14
min=27
s=5

dwhole = 367*y - INT(7*(y+INT((m+9)/12))/4) +INT(275*m/9)+d-730531.5
dfrac = (h + min/60 + s/3600)/24

Print dwhole
Print dfrac

Right now I need this on the Arduino…

** int y=2012;**
int m=2;
int d=13;
int h=14;
int min=27;
int s=5;
float dwhole;
float dfrac;

dwhole=367y - INT(7(y+INT((m+9)/12))/4) +INT(275*m/9)+d-730531.5;
dfrac = (h + min/60 + s/3600)/24;
Serial.println(dfrac);
Serial.println(dwhole);

Clearly the lines in RED cannot be used as they contain the function INT() which does not exist…

I tried to split the function up using integer variables to simulate the INT() function but I’m getting different results so for example the dwhole part would be like this:

int part1=(m+9)/12;
 part1=part1+y;
 int part2=275*m/9;
 int part3=7*part1/4;
 
 dwhole=(367*y)-part3+part2+day-730531.5;

I have attached an excel spreadsheet which give the answer

Please can someone explain where I am going wrong…

Sidereal calculator.xlsx (36.1 KB)

What is the INT() function suppose to do?

Sorry INT() returns the WHOLE number so

a=123.4325

a=INT(a)

Print a

Would display "123"

y=2012
m=2
d=13
h=14
m=27
s=5

Which m do you mean?

The arduino equivalent of INT() is int(). See reference pages.

Or you can use 'trunc'. See math.h.

dxw00d: y=2012 m=2 d=13 h=14 m=27 s=5

Which m do you mean?

The arduino equivalent of INT() is int(). See reference pages.

Sorry I've corrected this......

Will try the int() I keep forgetting about case sensitivity :D

It compiles now :D

Is this line legal (with dwhole as a float) ?

Serial.println(dwhole);

Works in my test version of your code.

cowasaki: Sorry INT() returns the WHOLE number so

a=123.4325 a=INT(a) Print a Would display "123"

Well in C, 'a' couldn't be 123.4325 if you made a an integer (int). If you do integer math and store it into an integer, there aren't any decimals left over. So there is no need for a function like the one used in BASIC.

int a = 13 /5;
Serial.println(a);

That would print "2".

 dwhole=(367*y)-part3+part2+day-730531.5;

Best not to mix an integer like "367" when doing float math. Best to make it a float as well: "367.0".

[quote author=James C4S link=topic=91821.msg689579#msg689579 date=1329165974]

cowasaki: Sorry INT() returns the WHOLE number so

a=123.4325 a=INT(a) Print a Would display "123"

Well in C, 'a' couldn't be 123.4325 if you made a an integer (int). If you do integer math and store it into an integer, there aren't any decimals left over. So there is no need for a function like the one used in BASIC.

int a = 13 /5;
Serial.println(a);

That would print "2".

[/quote]

I know but the resultant variable is a float and parts of the equation need to be integerised part way through the equation.

dxw00d: Works in my test version of your code.

It gives the wrong answer though!

dwhole should equal 4425.5 & dfrac should equal 0.602141204

So I thought it might be printing the address or something like that rather than the floating point number.

That'll be down to mixing integer and floating point maths.

dxw00d: That'll be down to mixing integer and floating point maths.

The input to the equation are all integers, should I convert them first ?

Try...

int y=2012;
int m=2;
int d=13;
int h=14;
int n=27;
int s=5;

float dwhole;
float dfrac;

void setup()
{
  Serial.begin(57600);

  dwhole=367.0*(float)y - 7.0*((float)y+int(((float)m+9.0)/12.0))/4.0 +int(275.0*(float)m/9.0)+(float)d-730531.5;
  dfrac = ((float)h + (float)n/60.0 + (float)s/3600.0)/24.0;

  Serial.println(dfrac);
  Serial.println(dwhole);
}

void loop()
{
}

dxw00d: Try...

int y=2012;
int m=2;
int d=13;
int h=14;
int n=27;
int s=5;

float dwhole; float dfrac;

void setup() {  Serial.begin(57600);

 dwhole=367.0*(float)y - 7.0*((float)y+int(((float)m+9.0)/12.0))/4.0 +int(275.0*(float)m/9.0)+(float)d-730531.5;  dfrac = ((float)h + (float)n/60.0 + (float)s/3600.0)/24.0;

 Serial.println(dfrac);  Serial.println(dwhole); }

void loop() { }

Thank you VERY much that works a treat!

I didn't know about the sticking (float) in front of a variable converted it.

It gives the same results as the spreadsheet now.

I didn’t know about the sticking (float) in front of a variable converted it.

It doesn’t convert it. The variable remains the same type.

What it does is cast it. That is it treats the value as though it was the type being cast to. So, in this case, it treats y, m, and d as though they had been defined as floats.

Also note the addition of '.0' to all the literals, to make them floats too.

dxw00d: Also note the addition of '.0' to all the literals, to make them floats too.

Thanks, much appreciated. I've not had to resort to floats in this language yet!

I've checked and double checked the maths but Excel and the Arduino don't quite come out with the same answer.

This is the current sketch.....

// Variables for return by function "siderealcalculations"

float sr_whole; float sr_frac; float sr_days; float gmst; float gmst360; float gmstHrs; int gmst_H; int gmst_M; int gmst_S;

// Variables for return by function "polestarlocate"

float polaris_posH; float polaris_posDeg;

void siderealcalculations(int y,int m,int d,int h,int mn,int s){

sr_whole=367.0*(float)y - 7.0*((float)y+int(((float)m+9.0)/12.0))/4.0 +int(275.0*(float)m/9.0)+(float)d-730531.5; sr_frac = ((float)h + (float)mn/60.0 + (float)s/3600.0)/24.0; sr_days = sr_whole + sr_frac; gmst = 280.46061837 + (360.98564736629 * sr_days); gmst360 = fmod(gmst,360.0); gmstHrs = gmst360/360.0*24.0; gmst_H = int(gmstHrs); gmst_M = int(gmst360*1.0/360.0*24.0*60.0)-gmst_H*60; gmst_S = int(gmst360*1.0/360.0*24.0*3600.0)-(gmst_H*3600)-(gmst_M*60);

}

// Note polestarlocate() relies on the function siderealcalculations having been called first

void polestarlocate(){ polaris_posH = fmod(((24.0-gmstHrs)/2.0)+1.25,12); polaris_posDeg = 30.0*polaris_posH; }

void setup() { Serial.begin(19200);

siderealcalculations(2012,2,13,14,27,5); polestarlocate();

Serial.println(sr_whole); Serial.println(sr_frac); Serial.println(sr_days); Serial.println(gmst); Serial.println(gmst360); Serial.println(gmstHrs); Serial.println(polaris_posH); Serial.println(polaris_posDeg); Serial.println(gmst_H); Serial.println(gmst_M); Serial.println(gmst_S); }

void loop() { }

and I posted the Excel test spreadsheet earlier.

Everything works until the SECONDS part of the calculation

Excel gets 13 seconds Arduino gets 30 seconds

I PRESUME this may well be down to precision but looking at it I wouldn't have thought that it would be that far out, unless I have messed something up and couldn't see it.

Being out by 17 seconds wouldn't be the end of the world for it's current application but I could do with it accurate if I can get it so as I will then add it to my library and can forget about it....

I really do appreciate the help. I normally program in Pascal (delphi) and assembly but have had to venture into C and JAVA recently. I am getting on with it but some syntax etc has confused me.

Thanks

730531.5

Time to read up on precision.

360.98564736629

Better go back and read it again.

A float on the Arduino is good for 6 to 7 digits of precision. The first value is pushing the limits. The 2nd is way over the edge.