Jump to content
Gord P

%G equivalent in FormatFloat?

Recommended Posts

I am using TChart which has property called AxisValueFormat for each axis.  It is the same as FormatFloat from what I can see.  This is somewhat restrictive it seems.

 

I have numbers that can be rather large (10^8), miniscule (10^-8), or in between (123.45).  With C or C++ this could be handled easily with %G.   However with FormatFloat it appears that you can have either scientific notation all the time (#.###E+00) or regular notation all the time (#.#####) but there is no way to set it up to automatically switch between the two depending on the number.  

 

If my graph has numbers between 0.1 and 1, I would rather have the axis labels look like 0.1, 0.2, 0.3, etc. as opposed to 1.0E-01, 2.0E-01, etc.

 

Is there way to do this easily with FormatFloat, or am I going to have to conditionally set the AxisValueFormat string depending on the mantissa that I will have to extract from the values?

Share this post


Link to post

That works with Format but not FormatFloat which is what AxisValueFormat is (I'm pretty sure).

 

 

Share this post


Link to post

Thanks for the suggestion.  Just tried it but it didn't work. Doesn't change it scientific notation when the numbers are really large.  

Share this post


Link to post

I ended up implementing a conditional AxisValuesFormat as follows

 

    double aNumber;
    int aExp;
    int order_of_mag = 2;
    
    // get aNumber somewhere (such as MaxXValue())

    aExp = int(fabs(log10(aNumber)));
    if (aExp > order_of_mag) Chart1->->LeftAxis->AxisValuesFormat = "0.00E+0";
    else Chart1->LeftAxis->AxisValuesFormat = "#,##0.###";

 

It's not the end of the world to have to implement something like this.  Not looking for a ton of performance at this place in the program.  You can change order_of_mag to any order of magitude you want to start using scientific notation.  Haven't tested it thoroughly yet to see if captures every scenario.

 

Share this post


Link to post
45 minutes ago, Gord P said:

Just tried it but it didn't work. Doesn't change it scientific notation when the numbers are really large.  

Well, FormatFloat acts as expected;

  for var I := 1 to 10 do
    Writeln(FormatFloat('', I/10));
  for var I := 1 to 10 do
    Writeln(FormatFloat('', I*Power10(1, 14)));

Output:

Quote

0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,9
1
100000000000000
200000000000000
300000000000000
400000000000000
500000000000000
600000000000000
700000000000000
800000000000000
900000000000000
1E15

 

Share this post


Link to post

That is true.  Where as what I want to see is:

 

0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
1.00E14
2.00E14
3.00E14
4.00E14
5.00E14
6.00E14
7.00E14
8.00E14
9.00E14
1.00E15

 

Which, AFAICS, requires an 'if' statement

 

Share this post


Link to post
2 hours ago, Gord P said:

It's not the end of the world to have to implement something like this.  Not looking for a ton of performance at this place in the program.  You can change order_of_mag to any order of magitude you want to start using scientific notation.  Haven't tested it thoroughly yet to see if captures every scenario.

That's a good start!  Say if you running a chemical treatment controller for million gallons of drinking water per day.  You set the Chart scale at 0 to 10 parts per million and gpm scaled zero to 1000 gpm either by fitting to your scale or add axis as needed .  Look at the graphs in white papers in the field you are working in to determine if part per million or part per billion.   Note Engineering Unit is SI or in US USCS known to some as field units requiring additional scaling need.      

Share this post


Link to post
4 hours ago, Uwe Raabe said:

Well, FormatFloat acts as expected;


  for var I := 1 to 10 do
    Writeln(FormatFloat('', I/10));
  for var I := 1 to 10 do
    Writeln(FormatFloat('', I*Power10(1, 14)));

That works for pH Scale. Closer range, scale and offset yields:

procedure TForm21.Button1Click(Sender: TObject);
const
  ZeroOffset = 7;
var
  X: double;
  I: Integer;
begin
  for I := -7 to 7 do
     begin
       X:= Power(10,I);

       Memo1.lines.add(Format('pH %d oh %G',[i + ZeroOffset,x]));
     end;
end;

(**
pH 0 oh 1E-007
pH 1 oh 1E-006
pH 2 oh 1E-005
pH 3 oh 0.0001
pH 4 oh 0.001
pH 5 oh 0.01
pH 6 oh 0.1
pH 7 oh 1
pH 8 oh 10
pH 9 oh 100
pH 10 oh 1000
pH 11 oh 10000
pH 12 oh 100000
pH 13 oh 1000000
pH 14 oh 10000000 **)

 

Edited by Pat Foley
add code

Share this post


Link to post
1 hour ago, Gord P said:

Where as what I want to see is:

Well, the FormatFloat implementation has the E15 hardcoded and even documented:

Quote

If the section for positive values is empty or if the entire format string is empty, the value is formatted using general floating-point formatting with 15 significant digits, corresponding to a call to FloatToStrF with the ffGeneral format. General floating-point formatting is also used if the value has more than 18 digits to the left of the decimal point and the format string does not specify scientific notation.

 

  • Thanks 1

Share this post


Link to post
On 10/20/2023 at 1:23 AM, Gord P said:

If my graph has numbers between 0.1 and 1, I would rather have the axis labels look like 0.1, 0.2, 0.3, etc. as opposed to 1.0E-01, 2.0E-01, etc.

I would suggest logarithmic graph for such data, give them a chance or at least research them.

Share this post


Link to post
On 10/21/2023 at 8:35 AM, Kas Ob. said:

I would suggest logarithmic graph for such data, give them a chance or at least research them.

You can't suggest that without knowing what the numbers represent. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×