Hello,
how can I send mor decimal places with Serial1.print
I have a variable
float x = 0.00324
Serial1.print(x);
On my terminal I get 0.00
Thanks.
Hello,
how can I send mor decimal places with Serial1.print
I have a variable
float x = 0.00324
Serial1.print(x);
On my terminal I get 0.00
Thanks.
Hi,
Try Serial1.print(x, 5);
Hi,
this doesn't work :(
Yes, you're right. On Arduino it works that way, but I forgot the Maple isn't compatible in that point (I discovered the same thing about six months ago but forgot).
But there's sprintf and probably others from newlib you can use. But they will eat a lot of flash :-(
ratho,
Thanks for the heads-up. Our Print implementation is adapted from an earlier version of Arduino's, which didn't specify a way to print out more than 2 decimal digits. I have updated our Print implementation to better track changes made to the Arduino version:
https://github.com/leaflabs/libmaple/commit/5c847fda31d956cc62c511a5fe277d197777de39
You can now give an optional number of digits argument when printing floating-point values.
If you're using the IDE, you'll have to make the changes in that commit yourself or wait for the next version to come out. If you're using the Unix toolchain, just pull the latest libmaple and let us know how it goes.
Hi,
thank you! Now it works :)
Is there a posibility to cut the 0?
If I use print(0.002, 5) I get 0.00200 -> always 5 positions after the decimal point.
Well the 5 means you want 5 decimals ;-)
You can use, for example, gcvt, which is a little smaller than sprintf. Like
#include <stdlib.h>
void setup()
{
}
void loop()
{
float x = 3.1415;
float y = 0.0021;
float z = 1.234e6;
char buf[20];
if (SerialUSB.available()) {
SerialUSB.read();
SerialUSB.println(gcvt(x,5,buf));
SerialUSB.println(gcvt(y,5,buf));
SerialUSB.println(gcvt(z,5,buf));
}
}
From the man-page (in linux):
DESCRIPTION
The gcvt() function converts number to a minimal length null-terminated
ASCII string and stores the result in buf. It produces ndigit signifi‐
cant digits in either printf(3) F format or E format.
Thank you! This works as desired :)
Hi,
After wasting half day trying to print a simple result such as 1234/53=23.283 I keep getting 23.00.
I have tried everything I know from any possible programming language print formatting (Basic, C, C++, Fortran, Java, C#.....) and only got errors.
Eventually, I searched the form and found out that the Maple does not have that VERY BASIC capability of simple decimal fraction number printing......
Well, I found out that there are new print.cpp and print.h from June 8, 2011 that are supposed to make it Arduino compatible (Arduino has all kinds of formatting) which I copied (NO download?) and replaced my older files, but for no avail.
Now I can get 23.0000000 which is 'better precision', but still worthless.
Is there a real solution or do I have to abndon my 2 new Maple boards?
I need math functions with readable results!!
#include <stdlib.h>
void setup()
{
}
void loop()
{
char buf[10];
float number = 1234/53; //=23.28301886792452830188679245283
SerialUSB.println(gcvt(number,5,buf)); //=23
SerialUSB.println( number,DEC); //=23.0000000000
SerialUSB.println(number,2); //=23.00
SerialUSB.println((float)number,2); //=23.00
delay(1000);
}
samtal
As far as the compiler knows, you're dividing two ints and then casting that to a float. You must show that you're using floats:
float number = 1234.0f / 53.0f;
You will end up with the following results:
23.283
23.2830181122
23.28
23.28
just as the println statements suggest they should be. No reason to abandon your Maple =]. It's a brilliant little board.
-robodude666
Indeed it works that way! (although my opinion is that the compiler should have understood that division of any two numbers is by default float)
I also noticed that one does not need both the decimal and the 'f'. Either is sufficient.
Here is how I read dual adc and break it down to volts: (I know there are other ways as well...)
void loop()
{
int read_result = ADC1_BASE->DR;
int adc1_data = (read_result & 4095);
int adc2_data = (read_result >>16 & 4095);
SerialUSB.print("ADC1_data: ");
SerialUSB.print((float)adc1_data / 4095 *3.3,3);
SerialUSB.print(" ADC2_data: ");
SerialUSB.println((float)adc2_data / 4095 *3.3,3);
SerialUSB.println();
delay (1000);
}
Not completely correct.
By omitting the f
, you are stating to the compiler that this number is a double. If you're storing a double in a float variable, a conversion may take place reducing overall performance. By including the f
, you are stating this is a float making the compiler's job easier. While it's not needed, it's good to have. If you're casting from an int to a float, a (float)
works too:
float number = (float)1234/(float)53;
-robodude666
samtal -
(although my opinion is that the compiler should have understood that division of any two numbers is by default float)
It often trips people up at first.
C and C++ have always used '/' to mean integer division when both operands are integers.
This is enshrined in all versions of the language from the original K&R definition through to modern ISO standards, so it isn't something recent :-)
It has several benefits:
1. operations on integers always yield an integer result. IMHO, this is a very easy rule to remember.
2. Integer division is a 'cheaper' operation than floating point division (especially on a microcontroller where these concerns matter more), so the lowest-cost operation is the default
3. It is easy to get floating point divide, for example float number = 1234.0f / 53.0f;
, or float number = 1234 / 53.0f;
, float number = 1234/(float)53;
, float x = 1234; number = x/53;
which all have the benefit of being more explicit and with less ambiguity.
4. There is no requirement for an extra 'integer divide' operator. Some languages have both a floating point divide and an integer divide operator (let's call integer divide 'div'). That can then get a bit weird if the programmer writes 1234 div 53.4
. In this sort of case, I think it is clearer, because it is more explicit, to write something like 1234 / trunc(53.5)
or trunc(1234 / 53.5)
(or the other options using round()
)
5. Floating point operations are inexact, for example, int i = (int)(1.0/3.0+1.0/3.0+1.0/3.0);
does not give 1, but integer operations are exact (noting that overflow stops that being true), so a default which is exact has significant advantages.
What operator would you use to show integer division if '/' means floating point division?
The operator would need to be non-alphanumeric characters, preferably in the ASCII range, to keep the language parser 'consistent' (i.e. not have to use even more powerful grammar mechanisms).
Edit: Division, like all float and double operations, should be carried out with double
precision if either operand is a float or double and the other integer. I believe it can be carried out in float
if both operands are float
(I think that was a C90/C99-ism, but might have been a GNU extension.)
HTH
robodude666
By omitting the f, you are stating to the compiler that this number is a double.
Agreed.
But it may be "worse than that Jim" :-)
It was true for several versions of C, starting at K&R, that mixed arithmetic had to be carried out in double
. So it can get quite costly (in CPU time).
(I just tried to check, but the ISO standards are not public! Why do we accept standards that are not published for free?)
I looked at the compiler documentation, but it refers to the standards :-(
You must log in to post.