1

I want to display only the mantissa of a number independently of what the exponent is.

12.4e-6 after formatting => 12.4

12.4e-12 after formatting => 12.4

To do the calculation manually is trivial. But the problem is that I need to use the class DeciamalFormat because I have to give it as argument to another class. I tried this:

DecimalFormat mFormat = (DecimalFormat) NumberFormat.getInstance();
mFormat.applyPattern("#.#E0");

if I remove the E symbol, the mantissa will not be calculated. is there any way using this DecimalFormat to show only mantissa?

canova
  • 3,965
  • 2
  • 22
  • 39
Cocomico
  • 878
  • 7
  • 18
  • `124e-7` = `12.4e-6` = `1.24e-5` = `0.124e-4` so you want to print a number where 124 = 0.124 ? – Peter Lawrey Mar 25 '14 at 10:07
  • or do you just want to multiply by 1e6? e.g. 12.4e-6 => 12.4 but 1.24e-6 => 1.24 and 1.24e-3 => 1240 – Peter Lawrey Mar 25 '14 at 10:09
  • `12.4e-6` = `12400000e-12` so which number do you want? – Peter Lawrey Mar 25 '14 at 10:10
  • I do not want to multiply by specific factor like 1e6. I want to have, say, two integer digits, then two decimal digits and ignore the exponent. 12.4e-12 => 12.4 (output is a String after formatting) 1233e-12 => 12133 0.12e-5 => 0.12 so just the Mantissa. – Cocomico Mar 25 '14 at 10:47
  • My point it that your stated requirement is meaningless because 1233e-12 is the same number as 1.233e-6 so under your requirements what should it print? You can't have multiple possible outputs for the same number. – Peter Lawrey Mar 25 '14 at 10:56
  • so basically it does not matter if the output string is the same for numbers that are different. Of course in my code I will take care of the exponents separately. So in the case where input is 12.4e-6, it will show 12.4 and in the case where input is 12400000-12 it will also show 12.4 because I have specified the format to show only two integer digits and one decimal digit. – Cocomico Mar 25 '14 at 11:10
  • So what would 1233e-12 be? 12.3 not 12133.0 – Peter Lawrey Mar 25 '14 at 11:12
  • `I have specified the format to show only two integer digits` I have no idea how to do this, nor how you believe this is what you did. You would have to write your own code to do that. – Peter Lawrey Mar 25 '14 at 11:14
  • yes, you are right. 1233e0 would be 12.3 – Cocomico Mar 25 '14 at 11:15
  • I have updated my answer to do what you suggest. – Peter Lawrey Mar 25 '14 at 11:29
  • Of course you can specify it: DecimalFormat mFormat = (DecimalFormat) NumberFormat.getInstance(); mFormat.applyPattern("#.#E0"); Double t1 = 1.5345e-6; Double t2 = 1000e-2; Double t3 = 1000.0; String output1 = mFormat.format(t1); // gives 1.5e-6 String output2 = mFormat.format(t2); // gives 1e-1 String output3 = mFormat.format(t3); // gives 1e3 now I just need to remove the e and what is after the e. – Cocomico Mar 25 '14 at 11:35
  • You just said you wanted *two* digits before the decimal point. `two integer digits and one decimal digit.` `1233e0` would turn into `1.2` if you use DecimalFormat. BTW its trivial to remove the exponent, it's getting a clear idea of what you want which is much harder, even harder is to understand the sanity of why. ;) – Peter Lawrey Mar 25 '14 at 11:37
  • Ok. Lets add a "#: mFormat.applyPattern("##.#E0") so everyone is happy. The point is that you can specify it. Regarding the purpose of doing this: I am measuring values that change from 1e-12 to 1e0 aproximately. I plot this values using aChartEngine. I want that the labels are shown without exponents and with a reasonable number of digits. I dont want to see something like 0.00000000024 in my chart. Depending on the exponent, I can dynamically change the y axis title to mW or uW or nW. I can only specify the labels format by giving an instance of the DecimalFormat as a paramater. – Cocomico Mar 25 '14 at 11:51
  • `Lets add a "#: mFormat.applyPattern("##.#E0") so everyone is happy.` That won't change what it does. When you use mW you multiply by 1e3, uW you multiply by 1e6 and nW you multiply by 1e9 and then you round to the precision you want. You don't just ignore the exponent. – Peter Lawrey Mar 25 '14 at 12:07
  • That is not as simple as multpilying. I tried that. The problem is, you record the first 1000 points and show them in your plot. Suddenly, new much bigger values have to be added to the plot, it means you have to multiply now by a smaller number (e.g scale will be changed from uW to mW). Then you have to iterate through all the previous 1000 points in your plot, and multiply them by the right factor and draw everything again. Consider that I am programing for android. So thats the worst solution regarding performance. – Cocomico Mar 25 '14 at 12:30
  • It depends on whether you want the plot to be fast, or have some meaning. You don't want to have 12.4 appear the same as 12.4 if one is actually 1000x the value of the other. – Peter Lawrey Mar 25 '14 at 12:57
  • As I said in a previous comment. In that case the yaxis title would change to the appropiate unit. e.g The plot shows in one case 12.4 with the ytitle mW and in the other case 12.4 with uW. I think it makes perfect sense. – Cocomico Mar 25 '14 at 13:07
  • So if you are going to do that you will want to control the units, multiply by 1e3 in the first case and 1e6 in the second case. – Peter Lawrey Mar 25 '14 at 13:16

3 Answers3

0

Im pretty sure you cant, as what your asking is for DecimalFormat to show a different number than what you are representing

Why not apply DecimalFormat to return the String 12.4 then substring the portion in front of the e if you need String format? Or just multiply out based on the exponent?

farrellmr
  • 1,815
  • 2
  • 15
  • 26
  • The reason I cannot do this is because I have to provide the DecimalFormat instance to a class that is performing its own calculations and then display the numbers based on the format specified. I have no control on the numbers being displayed by this class other than speicifying the format with the DecimalFormat class. – Cocomico Mar 25 '14 at 10:53
  • Is the DecimalFormat passed as a parameter? If so can you extend it as a custom decimalformat? – farrellmr Mar 25 '14 at 11:33
  • Yes it is passed as a parameter. I would like to be able to extend it but have searched for examples with no succsess. – Cocomico Mar 25 '14 at 11:42
  • [Example 1](http://stackoverflow.com/questions/673841/how-can-i-make-java-text-numberformat-format-0-0d-as-0-and-not-0) Or [Example 2](http://www.daniweb.com/software-development/java/threads/215148/custom-numberformat) – farrellmr Mar 25 '14 at 11:58
  • Excellent! I wrote my own function and it seems to work. Thanks. I will be posting the answer with the code soonish. – Cocomico Mar 25 '14 at 12:46
0

To get 2 decimal places before the digits and one after you can do the following.

String s = String.format("%4.1f", d / 
                              Math.pow(10, (int) (Math.log10(Math.abs(d)) - 1)));

Of course believing that the number after 999 => 99.9 is 1000 => 10.0 is just madness.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

I have found following solution: I override the methods of the NumberFormat class so that I can manipulate how the Double values are transformed into Strings:

public class MantissaFormat extends NumberFormat {  
@Override
/** Formats the value to a mantissa between [0,100] with two significant decimal places. */
public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) {

String output;
String sign="";

if(!isFixed)
{
    if(value<0)
    {
      sign = "-";
      value = -value;
    }

    if(value!=0) {

        while(value<1) {            
          value *= 100;
        }  
        while(value>100){                   
         value/=100; 
        }    
    }
}
// value has the mantissa only. 
output = sign + String.format( "%.2f", value );    
buffer.append(output);
return buffer;
}

@Override
public Number parse(String string, ParsePosition position) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();    
}
Cocomico
  • 878
  • 7
  • 18