Java getBytes() method is stripping .00 from numbers in my String - java

I'm generating a csv file and I have a bunch of numbers without decimal points and I'm being required to put .00 for those cases, I'm using:
DecimalFormat f = new DecimalFormat("#.00");
So fa so good I can see a string looking this way:
String myStringWithDecimalPoints = "124.00, 24567868.00, 5.00"
but when I do:
out.write(myStringWithDecimalPoints.getBytes());
I get in my csv:
124, 24567868, 5
Why is this happening?
Any workarounds? (it does have to be CSV and .00 must appear)

You have to be careful with how you view your data, especially in spreadsheets like Excel where the format of the output depends on the type of the cell. It may or may not show decimal values.
A note for the future, with a call like
out.write(myStringWithDecimalPoints.getBytes());
you can safely assume that Java is writing all the bytes to the OutputStream. If you're not seeing the same thing in the receiving side, then the receiving isn't being done like you would expect.

Most likely there is some confusion between the value of your original string, and how your string appears when you output it in certain ways using your formatter. This does not necessarily mean that your "original" string has been altered.
We could say with greater certainty if you provided a more complete code example.

Related

How to cast from String to BigDecimal with the separator as a comma? [duplicate]

This question already has answers here:
Java BigDecimal can have comma instead dot?
(3 answers)
Closed 3 months ago.
I have a method to set a BigDecimal number that is given as String:
private Client mapClient(Client client){
ClientRequest clientRequest = new ClientRequest();
// Code
clientRequest.setCashAmount(castStringToBigDecimal(client.getCashAmount()));
// More Code
}
My castStringToBigDecimal method is the follosing:
public BigDecimal castStringToBigDecimal(String value){
BigDecimal response = null;
if(value != null && !value.equals("")){
value = value.replaceAll("[.]", ",");
response = new BigDecimal(value);
}
return response;
}
An example of the input value is "1554.21"
I need that the bigDecimal separator to be a comma, not a dot. But this is giving me an exception.
EDIT
The value is the following:
And the exception is:
java.lang.NumberFormatException: Character , is neither a decimal digit number, decimal point, nor "e" notation exponential mark.
BigDecimal doesn't represent a rendering. In other words, whether to use a comma or a dot as separator is not part of the properties a BigDecimal object has.
Hence, you do not want to call .replaceAll. (And separately, you'd want .replace(".", ",") - replace replaces all, and replaceAll also replaces all and interprets the first arg as a regex, and is therefore needlessly confusing here). Just pass it with the dot.
To render a BigDecimal, don't just sysout it, that will always show a dot and there is nothing you can do about that. toString() is almost never the appropriate tool for the job of rendering data to a user - it's a debugging aid, nothing more. Use e.g. String.format("%f"), specifying the appropriate locale. Or use NumberFormat. The javadoc of BigDecimal explicitly spells this out.
There are various other issues with your code:
"cast" is the technical name for the syntactic construct: (Type) expr; - and this construct does 3 utterly different things, hence using it to describe a task, i.e. use it in a method name, is a very bad idea. In particular, only one of the 3 things it does converts anything, and you clearly use it here in the 'convert something' meaning. This is misleading; only if it's all primitives does the cast operator convert, and BigDecimal isn't primitive. Call it convertTo or whatever you please, not "cast".
BigDecimal is an extremely complicated tool for the job and usually not the right tool if you want to represent financial data. Instead, represent the atomary unit in a long and call the appropriate rendering method whenever you need to show it to a user. For example, for euros, the atomary unit is the eurocent. If something costs €1,50, you'd store "150", in a long. Before you think: But, wait, I want to divide, and then I'd lose half a cent! - yes, well, you can't exactly send your bank a request to transfer half a cent, either. Also, try to divide 4 cents by 3 with a BigDecimal and see what happens. Dividing financial amounts is tricky no matter what you use, BD isn't a catch-all solution to this problem.
I looked up the source code for Java 8's implementation of BigDecimal (https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/java/math/BigDecimal.java), and the period character is hard-coded in that source as the decimal point. I would not have thought this of a language for which internationalization has been so thoroughly designed in, but there it is, line 466.
Given that the author(s) of BigDecimal failed to take locale into account in such a basic way -- the use of comma instead of period as the decimal separator in Europe is well-known -- I'd have to say you cannot use that BigDecimal constructor on unaltered Strings that are otherwise formatted correctly but which (might) have a comma separator. There are other options -- the previous SO post referred to in one of the comments has one -- but it appears you cannot convert your String this way.
(One minor point -- you are not "casting" anything. That word has a specific meaning in OO programming, and a more specific one in Java, and has very little to do with your question. It is incorrect to refer to conversion as casting.)

Java: Simple format standard for various precision data

I'm trying to format output for user/report appeal, and there are two criteria I'm finding to be in a bit of conflict.
First, the decimal values should line up (format on "%12.10f", predicted integer value range 0-99)
Second, the decimal shouldn't trail an excessive series of zeroes.
For example, I have output that looks like
0.5252772000
0.2053628186
10.5234500000
But using a general formatting, I also end up with:
0.53260000000
0.52630000000
12.43540000000
In certain cases, and it looks kind of garbage.
Is there a simple way to solve this problem? The only solution I can come up with at the moment involves pre-interrogating the data before printing (instead of formatting it during print) which, while technically not expensive, just bugs me as being redundant data handling (ie I have to go through all data once to find the extrema of trailing zeroes to parse against it, and then set the format so that it can go through the data again to parse it)
You can set a DecimalFormat:
DecimalFormat format = new DecimalFormat("0.#");
for (float f : yourFloats){
System.out.println(format.format(f));
}
This also works on doubles.

Java NIO: Writing File Header - Using SeekableByteChannel

I am manually serializing data objects to a file, using a ByteBuffer and its operations such as putInteger(), putDouble() etc.
One of the fields I'd like to write-out is a String. For the sake of example, let's say this contains a currency. Each currency has a three-letter ISO currency code, e.g. GBP for British Pounds Sterling.
Assuming each object I'm serializing just has a double and a currency; you could consider the serialized data to look something like:
100.00|GBP
200.00|USD
300.00|EUR
Obviously in reality I'm not delimiting the data (the pipe between fields, nor the line feeds), it's stored in binary - just using the above as an illustration.
Encoding the currency with each entry is a bit inefficient, as I keep storing the same three-characters. Instead, I'd like to have a header - which stores a mapping for currencies. The file would look something like:
100
GBP
USD
EUR
~~~
~~~
100.00|1
200.00|2
300.00|3
The first 2 bytes in the file is a short, filled with the decimal value 100. This informs me that there are 100 spaces for currencies in the file. Following this, there are 3-byte chunks which are the currencies in order (ASCII-only characters).
When I read the file back in, all I have to do is build up a 100-element array with the currency codes, and I can cheaply / efficiently look up the relevant currency for each line.
Reading the file back-in seems simple. But I'm interested to hear thoughts on writing-out the data.
I don't know all the currencies up-front, and I'm actually supporting any three-character code - even if it's invalid. Thus I have to build-up the table converting currencies to indexes on-the-fly.
I am intending on using a SeekableByteChannel to address my file, and seeking back to the header every time I find a new currency I've not indexed before.
This has obvious I/O overhead of moving round the file. But, I am expecting to see all the different currencies within the first few data objects written. So it'll probably only seek for the first few seconds of execution, and then not have to perform an additional seek for hours.
The alternative is to wait for the stream of data to finish, and then write the header once. However, if my application crashes and I haven't written-out the header, the data in the file cannot be recovered back to its original content.
Seeking seems like the right thing to do, but I've not attempted it before - and was hoping to hear horror-stories up-front, rather than through trial/error on my end.
The problem with your approach is that you say that you do not want to limit the number of currency codes which implies that you don’t know how much space you have to reserve for the header. Seeking in a plain local file might be cheap if not performed too often, but shifting the entire file contents to reserve more room for the header is big.
The other question is how you define efficiency. If you don’t limit the number of currency codes you have to be aware of the case that a single byte is not sufficient for your index so you need either a dynamic possibly-multi-byte encoding which is more complicated to parse or a fixed multi-byte encoding which ends up taking the same number of bytes as the currency code itself.
So if not space-efficiency for the typical case is more important to you than decoding efficiency you can use the fact that these codes are all made up of ASCII characters only. So you can encode each currency code in three bytes and if you accept one padding byte you can use a single putInt/getInt for storing/retrieving a currency code without the need for any header lookup.
I don’t believe that optimizing these codes further would improve you storage significantly. The table does not consist of currency codes only. It’s very likely the other data will take much more space.

Which kind of representation can be '\r\x00\x00\x00' (if usually I have hexadecimal code:'\x0\x00\x00\x03')

I'm using a program (klee) that give me tests of c code.
I need to use the results in my program.
It is not readable information, but some of the solutions are hexadecimal data with the next format:
'\x0e\x00\x00\x00'
I have already asked about how to convert it into integer, and I found the solution.
I will have to introduce this kind of results in structs too, I will know the size but any about the fields or anything else about it.
I think I can solve this but now the problem is that sometimes you can obtain things like:
'\n\x00\x00\x00'= 13
or
'\r\x00\x00\x00' = 10
And I didn't found which kind of representation they use to convert it in readable information..
Apparently I could solve this in python with:
import struct
selection = struct.unpack('
I don't have any idea of pyton, and I would like found a solution in java or c.
Thanks very much
The value \n\r is used by Windows systems to indicate a newline - the \n moves to the new line, and \r moves the write pointer to the start of the line. I'm thinking that you might have had some character data containing a newline where each character was converted into a 32-bit integer value in big-endian format.
Hope this helps!

Inserting custom String between number and decimal - Java DecimalFormat

Hello and thank you in advance for the help.
I am having some trouble formatting using a Java function to mark up a price in HTML.
It seems that, no matter what I do, I cannot insert custom content between the numbers and the decimal (throws Illegal Argument Exception). Is there any known way to achieve the following:
NumberFormat nf = getNumberFormat("'<span class=\"dollars\">'##'</span></span class=\"decimal\">'.'</span></span class=\"cents\">'00'</span>'", locale);
nf.format(number);
Assume locale and number are correctly initialized.
If you look at the docs for DecimalFormat you'll see that they talk about the prefix and the suffix text - but not putting arbitrary text within a number.
It sounds like you should basically write this bit of formatting yourself - possibly using DecimalFormat for each section of the number.
You might consider using String.format(String pattern, Object... arguments). You can pass your simply formatted numbers as arguments.

Categories