ninja2
Well-known member
I'm developing a teensy sketch and MATLAB script in parallel, but my limited experience with high precision/high accuacy maths has led me following differences in calculated &/or reported values.
MATLAB uses double precision by default. My "equivalent" teensy sketch also uses doubles.
When I define an angle constant in degrees, convert it to radians and take the tangent the resulting answers are an exact match to 6 decimal places, but they vary in higher precision digits.
angle = -66.75828º
tan() = -2.3284907725008 (MATLAB)
tan() = -2.328490478388 (teensy)
Even the initial conversion to radians is similarly 'inaccurate'. I was expecting (and need) much more accuracy!
I figured maybe it was just the output/printing method, so I tested several (including dtostrf). The best I got was exact equivalence (between MATLAB and teensy) to 8 digits.
Looking for clues as to what I am missing?
Any and all solutions gladly accepted
Below are:
1) simple teensy sketch
2) output from the sketch
3) output from MATLAB script
Output from the sketch
######## t3Dtest ########
* Serial open, millis: 485
------ ------- -------
** angle A ...
input A: -66.75828(degrees) * D2R
A: -1.165151743170 (radians)
tan(): -2.328490478388
input A2: -1.16515178897 (radians)
A2: -1.165151834488
tan(): -2.328491064822
------ ------- -------
** dnum ...
input: -1.01234567890123456789
dtostrf: -1.01234567165374755859
.print: -1.012345671653747
_FLOAT: -1.012345671653747
------ end setup -------
Output from MATLAB script
Dtest
_angle = -66.75828º
radian = -1.16515178897
_tan() = -2.3284907725
tand() = -2.3284907725
>>
MATLAB uses double precision by default. My "equivalent" teensy sketch also uses doubles.
When I define an angle constant in degrees, convert it to radians and take the tangent the resulting answers are an exact match to 6 decimal places, but they vary in higher precision digits.
angle = -66.75828º
tan() = -2.3284907725008 (MATLAB)
tan() = -2.328490478388 (teensy)
Even the initial conversion to radians is similarly 'inaccurate'. I was expecting (and need) much more accuracy!
I figured maybe it was just the output/printing method, so I tested several (including dtostrf). The best I got was exact equivalence (between MATLAB and teensy) to 8 digits.
Looking for clues as to what I am missing?
Any and all solutions gladly accepted
Below are:
1) simple teensy sketch
2) output from the sketch
3) output from MATLAB script
Code:
#define LED LED_BUILTIN
#include <Streaming.h> // NB: with CJ edits to avoid SdFat/endl conflict
const double D2R = DEG_TO_RAD; // degrees to radians
const double angle = -66.75828 * D2R; // (radians) +ve for Northern hemisphere, -ve for Southern
const double angle2 = -1.16515178897;
char valBuffer[25] = {0};
const double dnum = -1.01234567890123456789; // width:23 precision:20
void setup() {
Serial.begin(115200);
while (!Serial && (millis() <= 4000)){ // wait for Serial to open, but only for 4 secs
digitalWriteFast(LED,!digitalReadFast(LED)); // toggle LED
delay(50);} // rapidly!
digitalWrite(LED, LOW); // then off
Serial << "######## t3Dtest ########\n";
Serial << F(" * Serial open, millis: ") << millis() << '\n';
Serial << "------ ------- -------" << '\n';
Serial << '\n';
Serial << "** angle A ..." << '\n';
Serial << "input A:\t-66.75828(degrees) * D2R" << '\n';
Serial << "A:\t"; Serial.print(angle,12); Serial << " (radians)"<< '\n';
Serial << "tan():\t"; Serial.print(tan(angle),12); Serial << '\n';
Serial << '\n';
Serial << "input A2:\t-1.16515178897 (radians)" << '\n';
Serial << "A2:\t"; Serial.print(angle2,12); Serial << '\n';
Serial << "tan():\t"; Serial.print(tan(angle2),12); Serial << '\n';
Serial << '\n';
Serial << "------ ------- -------" << '\n';
Serial << "** dnum ..." << '\n';
Serial << "input:\t-1.01234567890123456789" << '\n';
dtostrf(dnum, 23, 20, valBuffer); // double in, width, precision, buffer
//ostrf(dnum, 14, 11, valBuffer); // double in, width, precision, buffer
Serial << "dtostrf:\t"; Serial.println(valBuffer);
Serial << ".print:\t"; Serial.println(dnum,20);
Serial << "_FLOAT:\t" << _FLOAT(dnum,20) << '\n';
Serial << "------ end setup -------" << '\n';
}
void loop() {
}
Output from the sketch
######## t3Dtest ########
* Serial open, millis: 485
------ ------- -------
** angle A ...
input A: -66.75828(degrees) * D2R
A: -1.165151743170 (radians)
tan(): -2.328490478388
input A2: -1.16515178897 (radians)
A2: -1.165151834488
tan(): -2.328491064822
------ ------- -------
** dnum ...
input: -1.01234567890123456789
dtostrf: -1.01234567165374755859
.print: -1.012345671653747
_FLOAT: -1.012345671653747
------ end setup -------
Output from MATLAB script
Dtest
_angle = -66.75828º
radian = -1.16515178897
_tan() = -2.3284907725
tand() = -2.3284907725
>>