0

I want to do some calculation with a list of String:

1.23

4.56

7.89

For accuracy, I want the convert the above String to int:

123

456

789

How to do that?

Sorry for my vague description. What I really need is no matter what the input is, the int value should hold the specific decimal:

Let say I need 4 decimal:

String:1 ; int: 10000

String:1.23 int: 12300

String:1.2345 int:12345

macemers
  • 2,194
  • 6
  • 38
  • 55

5 Answers5

6

I would strip out the dots then parse as an int:

int i = Integer.parseInt(str.replace(".", ""));

If you need there to always be 3 digits, this approach gets ugly, but doable:

int i = Integer.parseInt((str.replace(".", "") + "00").replaceAll("^(...).*", "$1"));

This avoids the vagaries of the imprecision of double values, which could lead to incorrect results due to truncation when casting from double to int.


Here's an example of imprecision problems:

int i = (int) (100 * Double.parseDouble("1.13")); // 112

This is because:

double d = Double.parseDouble("1.13"); // 112.99999999999999
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 2
    @zavior no. I'm (deliberately) using `replace()` which uses plain text search term, not `replaceAll()` which uses regex. – Bohemian Feb 22 '14 at 10:11
  • Except it will convert 1.1 to 11 – Peter Lawrey Feb 22 '14 at 10:13
  • @PeterLawrey it's supposed to as I read the question. Admittedly, it is unclear if the final scale should always be 3 digits or if it should just match the input. I have assumed the simplest interpretation – Bohemian Feb 22 '14 at 10:13
  • 1
    @Bohemian In that case, with 15 digits of precision, double isn't going to have precision errors. – Peter Lawrey Feb 22 '14 at 10:17
  • 1
    @PeterLawrey Unfortunately, you are mistaken: `int i = (int)(100 * Double.parseDouble("1.13")); // 112` – Bohemian Feb 22 '14 at 10:33
  • @Bohemian Every programming should know how to round floating point numbers. ;) See my answer. – Peter Lawrey Feb 22 '14 at 10:45
  • @PeterLawrey sure, but it can be a trap. if you blast the dots it's just simpler code and less==good :) Oh and congrats 200K! – Bohemian Feb 22 '14 at 10:55
  • @Bohemian true if you want ".1.2.3.4." to parse, this is solution you want but I have found hacking numbers as text is more likely to case problems. – Peter Lawrey Feb 22 '14 at 10:59
  • 1
    @Bohemian If I have 1.23 and your method can convert it to 123 but what if 1.2 and 120 is what I want? Seems your method doesn't help in this case – macemers Feb 22 '14 at 13:31
  • It's a pity you didn't give that as an example when asking. I've added a solution, but I'd go to Peter's answer if you need always 3 digits. – Bohemian Feb 22 '14 at 14:14
  • @PeterLawrey Aggghh! You're right! See recent comment by OP. – Bohemian Feb 22 '14 at 14:15
3

You can use

long n = Math.round(Double.parseDouble(text) * 100);

This will mean numbers like 0.1 will be 10 not 1 and 1.110 will be 111 not 1110

Let say I need 4 decimal:

String:1 ; int: 10000

String:1.23 int: 12300

String:1.2345 int:12345

needs

long n = Math.round(Double.parseDouble(text) * 10000);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I saw your presentation about HFT system in Java before, it's very helpful. This is what I need but I have a little concern: what's the performance of Math.round(Double.parseDouble(text) * 100);? – macemers Feb 24 '14 at 04:13
  • @user838204 It's the best option you have. Parsing from text is relatively expensive as is creating a String object. However you should be able to do this in well under a micro-second. – Peter Lawrey Feb 24 '14 at 10:41
  • thanks for the supplements. I have another urgent questions about the quickfix ,would you please help to take a look? http://stackoverflow.com/questions/22004162/weird-behavior-of-quickfix-j-after-sent-test-request-test-happens – macemers Feb 25 '14 at 03:49
2

You can replace all dots with empty strings (text.replace(".", "")) and then use Integer.parseInt(text).

Mateusz
  • 3,038
  • 4
  • 27
  • 41
1

For one String, you can do:

private static final BigDecimal ONE_HUNDRED
    = new BigDecimal(100);

// In code:
new BigDecimal(inputString).multiply(ONE_HUNDRED).intValueExact();

Note the use of BigDecimal here; a double will NOT do.

Note also that it will work only if the input has at most two decimal digits: if more than that, .intValueExact() will throw an exception (it will also throw an exception if the decimal integer is out of bounds for an int).

Now, it depends on how precise you need to be; this method guarantees the results. The method to remove dots and parse as int is obviously faster ;)

fge
  • 119,121
  • 33
  • 254
  • 329
  • You could just use the `BigDecimal` itself rather than turning it into an `int` - this would obviously allow for arithmetic with arbitrary decimal numbers. – Boris the Spider Feb 22 '14 at 10:20
  • Well, since the OP seems to want an int... But obviously yes, you can go `BigDecimal` all the way as well. – fge Feb 22 '14 at 10:21
  • yup - but it's often the case the the OP doesn't know what they want. For example they might have read an ancient blog post about not using `double` for arithmetic with money and to multiply things up and use an `int`... – Boris the Spider Feb 22 '14 at 10:22
  • We agree on that one ;) – fge Feb 22 '14 at 10:23
0

I will suggest you use string.replace and replace all "." with "". Then you can use Integer.parseInt(str) and you will have the result.

str = str.replace(".", "");
int val = Integer.parseInt(str);
Mobility
  • 263
  • 2
  • 5