Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Method:

  • Input: a string which represents an integer or a non-integer value.
  • Output: a string which represents the same value multiplied by 100.

Requirements:

  • No floating-point unless needed.
  • No leading 0s in the part left of the floating-point.
  • No trailing 0s in the part right of the floating-point.

I cannot use the Double.parseDouble method, because it sometimes yields an "ugly" result.

For example:

String.valueOf(Double.parseDouble("0.0071")*100)); // yields 0.7100000000000001
String.valueOf(Double.parseDouble("0.072" )*100)); // yields 7.199999999999999

Here is my code, and I would like to know if there are any cavities in it:

String MultiplyBy100(String number)
{
    StringBuilder sb = new StringBuilder();

    String[] parts = number.split("\\.");
    if (parts.length == 1)
        sb.append(parts[0]+"00");
    else if (parts[1].length() == 1)
        sb.append(parts[0]+parts[1]+"0");
    else if (parts[1].length() == 2)
        sb.append(parts[0]+parts[1]);
    else
        sb.append(parts[0]+parts[1].substring(0,2)+"."+parts[1].substring(2));

    if (sb.charAt(0) == '-')
    {
        while (sb.length() > 2 && sb.charAt(1) == '0' && sb.charAt(2) != '.')
            sb.deleteCharAt(1);
    }
    else
    {
        while (sb.length() > 1 && sb.charAt(0) == '0' && sb.charAt(1) != '.')
            sb.deleteCharAt(0);
    }

    return sb.toString();
}
share|improve this question
    
If your input is the string '0' will the output be the string '000'? –  githubphagocyte Mar 20 at 20:51
    
@githubphagocyte: No, why would it be? –  barak manos Mar 20 at 20:57
    
My apologies - I see my mistake now. –  githubphagocyte Mar 20 at 21:02
    
@palacsint already answered this, but in a nutshell the issue is simply that floating point data types are imprecise and math operations on floats produce rounding errors at the edge of the precision of the data type (turning 0.0071 into 0.007100000000000001 for instance). That is totally fine as long as the error falls outside the precision you require. Decimal data types (scaled integers) on the other hand are not subject to those rounding errors. Math results from decimal types will be as precise as the inputs. Caveat: decimal operations are extremely slow compared to floats. –  Craig Mar 21 at 12:23
    
Also, my comment that "Math results from decimal types will be as precise as the inputs" was on the simplistic side, but these comment fields are short. The results will be as precise as the least precise of the inputs, and still not always perfect mathematically, and quite slow because the operations are 100% software with no help from specialized hardware. The decimal data type is fundamentally the same thing whether you're dealing with Java, C#, C++, MySQL or SQL Server. This post is informative –  Craig Mar 21 at 12:33

2 Answers 2

up vote 10 down vote accepted
  1. It would be much easier with BigDecimals:

    String input = "00007.880000";
    BigDecimal hundred = BigDecimal.valueOf(100);
    BigDecimal result = new BigDecimal(input).multiply(hundred).stripTrailingZeros();
    
    System.out.println(result.toString()); // prints "788"
    

    It works with big numbers well:

    String input = "0000123456789123456789.123456789123456789123456789123456789880000";
    BigDecimal hundred = BigDecimal.valueOf(100);
    BigDecimal result = new BigDecimal(input).multiply(hundred).stripTrailingZeros();
    
    // prints "12345678912345678912.345678912345678912345678912345678988"
    System.out.println(result.toString()); 
    

    Two readings:

  2. The original code returns 788.0000 for 00007.880000 which I guess does not fulfill the specification.

  3. Java developers usually start method names with lowercase letters.

    Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

    Source: Code Conventions for the Java TM Programming Language, 9 - Naming Conventions

share|improve this answer
1  
So much for the answer I was half way through –  rolfl Mar 20 at 12:29
    
What about 1.234? Will BigDecimal yield 123.4? –  barak manos Mar 20 at 12:31
1  
@barakmanos you should read the documentation and try this. It will help you learn. But, yes, it will. –  rolfl Mar 20 at 12:32
    
Oh... was probably thinking of BigInteger... –  barak manos Mar 20 at 12:33
1  
Thanks. Regarding your second comment: I assume that the input is already "aligned" with the requirements of the output, so 00007.880000 is not a viable input in my program (though, I should have probably mentioned that in the question). Regarding your third comment: I know, it's just a typo (happened when I copied the code I wanted to be reviewed into a separate method). Thanks again for the detailed answer. –  barak manos Mar 20 at 15:22

Aside from palacsint's great suggestions:

  • You are using a StringBuilder, yet you still are doing string concatenations.

  • Your code for removing the leading zeros duplicates the for while loop.

Also: Why is your original input a string? This doesn't feel right. I've got the feeling there is something wrong with the bigger picture of your code.

EDIT: I meant the while loops. Better would be something like:

int startAt = sb.charAt(0) == '-' ? 1 : 0;

while (sb.length() > startAt + 1 && sb.charAt(startAt) == '0' && sb.charAt(startAt + 1) != '.')
   sb.deleteCharAt(startAt);

EDIT 2: Better readable?

boolean negative = sb.charAt(0) == '-';
if (negative) sb.deleteCharAt(0);

while (sb.length() > 1 && sb.charAt(0) == '0' && sb.charAt(1) != '.')
  sb.deleteCharAt(0);

if (negative) sb.insert(0, '-');

(Add brackets to taste)

share|improve this answer
    
Thanks. What do you mean by "duplicates the for loop"? First of all, there are no for loops in my question, only while loops. Second, I don't see how they are duplicated. My original input is a String because I read it from a file, and if I read it as Double, then... well, you can guess what might happen... –  barak manos Mar 20 at 15:25
    
@barakmanos See edit. –  RoToRa Mar 20 at 15:31
    
Oh, so the duplication is only in terms of coding... Well, true, but your suggestion makes it slightly harder to read I suppose... –  barak manos Mar 20 at 15:33
    
@barakmanos See another edit. –  RoToRa Mar 20 at 15:41
    
OK, thanks :) ... –  barak manos Mar 20 at 15:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.