how can i only have the first 5 numbers in a double?
12345.6789 --> 12345
1.23456789 --> 1.2345
0.123456789 --> 0.1234
I have tried different things such as multiplying the number by the power of 10 and x
but x seems to only affect the decimal places, setting it to x decimal places
Using BigDecimal:
move the decimal point to the right/left until only the desired number of (significant) digits are in front of the decimal point;
set the scale to zero, that is, removed all digits after the decimal point or extend the precision up to the point (if missing digits);
move the decimal point back to where it was, undoing first step.
static BigDecimal convert(BigDecimal number, int significant) {
var beforeDecimal = number.precision() - number.scale();
var movePoint = significant - beforeDecimal;
return number
.movePointRight(movePoint)
.setScale(0, RoundingMode.DOWN)
.movePointLeft(movePoint);
}
called like
convert(BigDecimal.valueOf(1.23456789), 5)
or
convert(new BigDecimal("1.23456789"), 5)
to return the BigDecimal:
1.2345
Here is one way.
convert to a string.
check for a decimal.
if not present (= -1) or >= 5, set i to 5. Else set to 6
then get the substring from 0 to i.
double[] v = {12345.6789,
1.23456789,
0.123456789};
for (double d : v) {
String s = Double.toString(d);
int i = s.indexOf('.');
i = i < 0 || i >= 5 ? 5 : 6;
System.out.println(s.substring(0,i));
}
prints
12345
1.2345
0.1234
As others commented, one way to do this is with string manipulation. May not seem elegant, but it gets the job done.
Define some inputs.
double[] doubles = { 12345.6789 , 1.23456789 , 0.123456789 } ;
Loop those inputs. For each one, generate a string. If a FULL STOP is found, take first six characters. If not, five. If the FULL STOP lands in the last place, such as in our first example input, delete.
for( double d : doubles )
{
String s = String.valueOf( d ) ;
String s5 = s.substring( 0 , s.contains( "." ) ? 6 : 5 ) ;
if( s5.endsWith( "." ) ) { s5 = s5.substring( 0 , s5.length() - 1 ) ; } // Drop FULL STOP in last place.
System.out.println( s5 ) ;
}
See this code run live at IdeOne.com.
12345
1.2345
0.1234
Caveat: You may need to internationalize by accounting for a COMMA (,) as the decimal separator rather than a FULL STOP (.) character.
String s5 = s.substring( 0 , ( s.contains( "." ) || s.contains( "," ) ) ? 6 : 5 ) ;
i ended up going with the following:
//cuts the string to the first 6 letters
String sixLetter = aDouble.toString().substring(0,6);
//checks if there is a "." before the 5th character so we don't end up with 12345.
if (sixLetter.indexOf(".") > 4) {
//then assuming there is not a "." it will cut it to the first 5 characters
return sixLetter.substring(0,5);
//if there is a "." (other than 12345.) it will cut it down to 5 characters resulting in 12345
};
return sixLetter;
Related
I'm attempting to go and generate a file with every Unicode variable. I have been able to get unicode up to U+FFFF, however I need to get it up to U+231F4. I've tried searching for answers, but none of them work when the symbol id is in a variable instead of just typed.
Right now, I have this:
for (int i = 0; i < 143860; i++) {
System.out.println((char)i);
}
Instead of going up to U+231F4, it instead goes up to U+FFFF, and loops in the document it is printing to. How do I make it go to higher Unicode IDs?
[ The OP said "I need to get it up to U+231F4", and I answered that. But what they meant is that they wanted to print the 143,859 Code Points defined by Unicode. See the other answer. I can't delete this now that
it's been accepted. ]
Java strings aren't made of Unicode Code Points but of UTF-16 code units. You need to use surrogate pairs for Unicode Code Points above U+FFFF. For example,
U+0 ⇒ 0x0000 ⎫
U+1 ⇒ 0x0001 ⎪
⋮ ⎬ Character in the BMP result
U+D7FE ⇒ 0xD7FE ⎪ in a single UTF-16 code unit.
U+D7FF ⇒ 0xD7FF ⎭
U+D800 ⇒ ------ ⎫
U+D801 ⇒ ------ ⎪
⋮ ⎬ Can't be encoded using UTF-16.
U+DFFE ⇒ ------ ⎪ Illegal for interchange for this reason.
U+DFFF ⇒ ------ ⎭
U+E000 ⇒ 0xE000 ⎫
U+E001 ⇒ 0xE001 ⎪
⋮ ⎬ Character in the BMP result
U+FFFE ⇒ 0xFFFE ⎪ in a single UTF-16 code unit.
U+FFFF ⇒ 0xFFFF ⎭
U+10000 ⇒ 0xD800, 0xDC00 ⎫
U+10001 ⇒ 0xD800, 0xDC01 ⎪
⋮ ⎬ Those outside result in two.
U+231F2 ⇒ 0xD84C, 0xDDF2 ⎪
U+231F3 ⇒ 0xD84C, 0xDDF3 ⎭
U+231F4 ⇒ 0xD84C, 0xDDF4 ⎫
U+231F5 ⇒ 0xD84C, 0xDDF5 ⎪
⋮ ⎬ We don't care about these.
U+10FFFE ⇒ 0xDBFF, 0xDFFE ⎪
U+10FFFF ⇒ 0xDBFF, 0xDFFF ⎭
For the details on surrogate pairs, you can consult the Wikipedia page for UTF-16.
Solution 1: printf %c
These details don't matter because we can use printf %c encode a Unicode Code Point into UTF-16 code units. (Kudos to #VGR.)
for (int cp=0; cp<0x231F4; ++cp) {
if (cp < 0xD800 || cp >= 0xE000) {
System.out.printf("%c%n", cp);
}
}
Optimized:
for (int cp=0; cp<0xD800; ++cp) {
System.out.println((char)cp);
}
for (int cp=0xE000; cp<0x10000; ++cp) {
System.out.println((char)cp);
}
for (int cp=0x10000; cp<0x231F4; ++cp) {
System.out.printf("%c%n", cp);
}
Solution 2: Character.toChars
Alternatively, we can use Character.toChars(codePoint) to produce a char[] containing the UTF-16 code units of a Unicode Code Point.
for (int cp=0; cp<0x231F4; ++cp) {
if (cp < 0xD800 || cp >= 0xE000) {
System.out.println(Character.toChars(cp));
}
}
Optimized:
for (int cp=0; cp<0xD800; ++cp) {
System.out.println((char)cp);
}
for (int cp=0xE000; cp<0x10000; ++cp) {
System.out.println((char)cp);
}
for (int cp=0x10000; cp<0x231F4; ++cp) {
System.out.println(Character.toChars(cp));
}
I believe the above still creates a lot of arrays. Implementing the conversion yourself avoids that and should thus be even faster.
// Up to but excluding U+231F4 ⇒ 0xD84C, 0xDDF4
for (int cp=0; cp<0xD800; ++cp) {
System.out.println((char)cp);
}
for (int cp=0xE000; cp<0x10000; ++cp) {
System.out.println((char)cp);
}
char pair[2];
for (int hisurro=0xD800; hisurro<0xD84C; ++hisurro)
pair[0] = (char)hisurro;
for (int losurro=0xDC00; losurro<0xE000; ++losurro)
pair[1] = (char)losurro;
System.out.println(pair);
}
}
pair[0] = 0xD84C;
for (int losurro=0xDC00; losurro<0xDDF4; ++losurro)
pair[1] = (char)losurro;
System.out.println(pair);
}
Note that result is not going to be entirely readable in your terminal. The output includes non-printable characters (e.g. control characters), marks (which combine with other characters), unassigned Code Points, private use Code Points, etc.
tl;dr
Here is a one-liner. (For fun, not what I would recommend.)
IntStream
.rangeClosed( 0 , Character.MAX_CODE_POINT )
.filter(
codePoint ->
!
List
.of( Character.CONTROL , Character.FORMAT , Character.SURROGATE , Character.PRIVATE_USE , Character.UNASSIGNED )
.contains( ( byte ) Character.getType( codePoint ) )
)
.forEach(
codePoint -> System.out.println( codePoint + " code point is named: " + Character.getName( codePoint ) + " = " + Character.toString( codePoint ) )
)
;
When run.
32 code point is named: SPACE =
33 code point is named: EXCLAMATION MARK = !
34 code point is named: QUOTATION MARK = "
…
917997 code point is named: VARIATION SELECTOR-254 = 󠇭
917998 code point is named: VARIATION SELECTOR-255 = 󠇮
917999 code point is named: VARIATION SELECTOR-256 = 󠇯
Avoid char
The char type in Java is obsolete. That data type is unable to represent even half of the characters defined in Unicode and supported by Java.
Java now offers full support of code points. Unfortunately, that support is not obvious, having been years later bolted on to aging APIs in Character, String , and StringBuilder classes. You have to look past the outmoded methods involving char.
Use code points
Get in the habit of using Unicode code point integers, without any char. A code point is a number assigned to each and every one of the 143,859 characters defined by Unicode.
Those code point numbers are assigned from a range 0 to 10FFFF hex, 0 to 1,114,111 decimal. Obviously most of that million-wide range is empty, either currently unassigned or set-aside as a reserve for private usage.
You said:
however I need to get it up to U+231F4.
No, you need to go to U+10FFFF (1,114,111 decimal).
By the way, Unicode is always growing. So, do not get attached to a character count such as 143,860. We can never have too many emojis! And some serious characters are still being added too.
So your loop:
for (int i = 0; i < 143_860; i++) { // NO! Wrong limit.
… needs to change its limit from 143_860 to 1_114_111 decimal (10FFFF hexadecimal).
for (int i = 0; i < 1_114_111; i++) { // YES! Correct limit.
Or, for this limit, use the constant Character.MAX_CODE_POINT.
for (int i = 0; i < Character.MAX_CODE_POINT; i++) { // Use named constant rather than "magic" mystery number.
One more thing… the MAX_CODE_POINT is inclusive, so we should be testing for "is less than OR equal to" rather than "less than". Change < to <=.
for (int i = 0; i <= Character.MAX_CODE_POINT; i++) { // Use named constant rather than "magic" mystery number.
The Character class can tell us if a code point is valid or not. All code points from 0 to the maximum 1,114,111 are valid numbers. Negative numbers and numbers over the maximum are invalid.
And that same class can tell us what kind of character is represented by a code point. The Unicode Standard defines 30 kinds, formally known as “General Category”. These categories are defined on the Character class as named constants, unfortunately mixed with other different constants.
We would like to skip over certain of those categories, specifically five:
Character.CONTROL
Character.FORMAT
Character.SURROGATE
Character.PRIVATE_USE
Character.UNASSIGNED
To determine the category of a code point, call Character.getType. Unfortunately, that method returns a mere int rather than a dedicated enum object.
As listed above, the Character class defines various byte constants for the general categories, but has no way to easily convert the number returned by getType into a category name. See the related Question, How to get the category name of the character type in Java?. There is a feature-request on the books, but not yet implemented. So we must roll-our-own.
Here we use a list of Byte objects named unicodeGeneralCategoryCodesToAvoid, one element for each of the five constants of interest.
To move from a code point int number to an actual character, call Character.toString( codePoint ) to produce a String containing a single character.
To get the official name for a character as defined by the Unicode Standard, call Character.getName( codePoint ).
List < Byte > unicodeGeneralCategoryCodesToAvoid = List.of( Character.CONTROL , Character.FORMAT , Character.SURROGATE , Character.PRIVATE_USE , Character.UNASSIGNED );
for ( int codePoint = 0 ; codePoint <= Character.MAX_CODE_POINT ; codePoint++ ) {
if ( Character.isValidCodePoint( codePoint ) ) // If code point is valid.
{
if ( unicodeGeneralCategoryCodesToAvoid.contains( ( byte ) Character.getType( codePoint ) ) ) // If control character or if unassigned code point, skip it.
{
// No code needed. Skip over this code point as it does not represent a printable character.
} else {
System.out.println( codePoint + " code point is named: " + Character.getName( codePoint ) + " = " + Character.toString( codePoint ) );
}
} else {
System.out.println( "ERROR - Invalid code point number: " + codePoint );
}
}
When run.
INFO - Demo starting.
32 code point is named: SPACE =
33 code point is named: EXCLAMATION MARK = !
34 code point is named: QUOTATION MARK = "
35 code point is named: NUMBER SIGN = #
36 code point is named: DOLLAR SIGN = $
37 code point is named: PERCENT SIGN = %
…
123 code point is named: LEFT CURLY BRACKET = {
124 code point is named: VERTICAL LINE = |
125 code point is named: RIGHT CURLY BRACKET = }
126 code point is named: TILDE = ~
160 code point is named: NO-BREAK SPACE =
161 code point is named: INVERTED EXCLAMATION MARK = ¡
162 code point is named: CENT SIGN = ¢
…
917997 code point is named: VARIATION SELECTOR-254 = 󠇭
917998 code point is named: VARIATION SELECTOR-255 = 󠇮
917999 code point is named: VARIATION SELECTOR-256 = 󠇯
INFO - Demo ending.
For more of my code for dealing with Unicode General Category, see my Answer to the Question, How to get the category name of the character type in Java?.
how to get the sum of no which contains 8 digit in array? For example we take input from user and stored in array i.e. 33,6,8,95,123,88 so the sum will be 8+88=96 ......So how to find out the array contains 8 digit .Whats the logic behind this ...can anybody explain this?
If you facing this kind of problem try to divide it into small parts and then try to solve them. In the end they will exhaustively solve the big problem.
By the way You can do this in 2 ways in java.
Split number into digit using modulus (% ) operator.
for ( int I = 0; i<arr.length ; i++){
value = arr[i];
while( value > 0 ){
if ( value%10 == 8 ){
// it contains 8.
// add arr[i] to total and break the loop
}
Value= value/10;
}
}
eg :- 108%10 = 8
convert your number in to String and use String#toCharArray() to
split it.
String value = String.valueOf( arr[i] ); // convert it to char array
Char [] digitList = value.toCharArray(); // add separate digit to char array
And then check the char array has digit 8.
For more on spiting digits view this question's answers.
Given this numbers:
150.00
150.26
I need to round like this:
If the second value of decimal part is zero (0), then the new value should be 150.0
If the second value of decimal part is different than zero (0), then the new value keeps both decimals Ex.: 150.26
Is there a rounding method that can do this?
Thanks.
My code here:
String monto = "150.10";//150.26
String nuevoMonto = "";
String[] valores = monto.split("\\.");
System.out.println("Valores : " + valores);
System.out.println("Valores length: " + valores.length);
for (int i = 0; i < valores.length; i++) {
System.out.println("-->Valor: " + valores[i]);
}
if (valores.length == 2) {
nuevoMonto = valores[1];
System.out.println("Nuevomonto: " + nuevoMonto);
if (nuevoMonto.length() == 2) {
System.out.println("Dos posiciones decimales");
System.out.println(nuevoMonto.indexOf("0"));
if (nuevoMonto.indexOf("0") == 1) {
nuevoMonto = valores[0] + "." + nuevoMonto.substring(0, 1);
}
}
}
System.out.println("Nuevo monto: " + nuevoMonto);
try something like this:
DecimalFormat decimalFormat = new DecimalFormat("#.0#");
System.out.println(decimalFormat.format(150.09));
System.out.println(decimalFormat.format(150.10));
The string inside the new decimal format allows #s to be trimmed, and 0s are forced to stay
If you have a string to start with, perhaps there is no point parsing it to a floating point number and then reformatting it. Another approach is to use a regexp for this:
String monto = "150.10";
String nuevoMonto = monto.replaceAll("(?<=\\.\\d)0$", "")
The regexp consist of two parts. The first part (?<=\\.\\d) says the match need to be preceded by a dot and a digit. The second part 0$ matches the trailing zero at the end of the string. We replace it with nothing.
There is an expression in Java called floor method which can be used to always bring a value with any form of rounding to an integer value with any relevant decimal points removed from the data
a simple check for this wold be to take the data and check if the data is not modulo or mod of a zero
sample code might look like this.
if ((monto % 0.1 ) == 0)
{
//has no relevant data so it should be floored
Nuevomonto = floor (monto);
}
else
{
Nuevomonto = monto;
}
hope that helps.
I have several thousands of rows that I'm loading into a database utilizing Pentaho. I must keep the string value length at 4 characters. The source file may only have a single character but it is still needed to keep the length at 4 characters to maintain consistency in the database.
Example:
Source: 10
Database expected results: 0010
I'm using a replace in string transformation or could use a java expression, which ever one works. Please help and provide a resolution utilizing either method (Regex or Javascript expression).
Thanks,
In Java you can use String.format(...) with a format specifier to pad your number with zeroes to 4 digits:
String.format("%04d", yournumber);
In Javascript you can use sprintf(...) for the same task:
var s = sprintf("%04d", yournumber);
So apparently sprintf() isn't standard Javascript but is a library you can download if you like. You can always to do this to get your 4 digits though:
// take the last 4 digits from the right
var s = String("0000" + yournumber).slice(-4);
And you could actually turn this into a simple left-padding function:
String.prototype.leftPad = function(paddingValue, paddingLength) {
return (new Array(paddingLength + 1).join(paddingValue) + this).slice(-paddingLength);
};
var s = String(yournumber).leftPad("0", 4)
(If you mean Javascript):
var str = "10";
function padIt(s) {
s = ""+s;
while (s.length < 4) {
s = "0" + s;
}
return s;
}
console.log(padIt(str));
http://jsfiddle.net/EzqRM/1/
For arbitrary padding of numbers, in javascript:
// padLeft(
// number to pad
// length to pad to
// character to pad with[optional, uses 0's if not specified]
// )
function padLeft(num, pad, padchr) {
num = "" + num;
pad = (pad || num.length) + 1;
return (num.length < pad ? new Array(pad - num.length).join(padchr || "0") : "") + num;
}
// returns "0010"
var input = 10
padded = padLeft(input, 4)
I am trying to make a program, that displays rather large numbers (BigInteger large). To make it easier for the user, I am displaying the numbers as string (1 000 000 = 1 Million). My below code shows my current attempt. My problem lies, in the fact that the actual number that I am replacing will not be nice and round. This program does not need to display the 100% accurate value, rather give a ball park figure. I.E:
1 234 567 = 1 Million
1 000 000 = 1 Million
1 934 234 = 1 Million
My current code (Shortened for brevity):
if (!displayNumbers) {
StringBuffer sb = new StringBuffer(_combinations);
String t = sb.reverse().toString();
Toast.makeText(getApplicationContext(), t, 1).show();
...
if (t.contains("000 000 000 000 000")) {
t.replace("000 000 000 000 000", "quadrillion");
}
if (t.contains("000 000 000 000")) {
t.replace("000 000 000 000", "trillion");
}
if (t.contains("000 000 000")) {
t.replace("000 000 000", "billion");
}
if (t.contains("000 000")) {
t.replace("000 000", "million");
}
sb = new StringBuffer(t);
_combinations = sb.reverse().toString();
}
I was thinking something along the lines of replacing the zero's with #'s so that it would just search for x lots of 3 digits and replace with corresponding word, but I do not know how to implement this. I should also note that I am aware that the million, billion, etc are currently spelt backwards in the final output string.
EDIT: Should note for UK readers that I am using USA definitions of *illions.
EDIT 2: Been doing some more Googling and found this - java Regex: replace all numerical values with one number. Except I have no idea how to modify the Regex for finding 000 000.
you can do that using if and else statements, from what I understand you're not looking for exact representation , so it is ok to say 1 Million for 1400000.
To do so you can use code like this:
int myValue
String txt = null;
if (myValue> 500 000 000){
txt = String.ValueOf((int) myValue/1000000000) + " Billion"
} else if (myValue> 500 000){
txt = String.ValueOf((int) myValue/1000000) + " Million"
} else if (myValue> 500) {
txt = String.ValueOf((int) myValue/1000) + " Thousand"
}
This should work for the simple usage you're describing.
Your number(in text) is just for display purpose. It's bad idea to manipulate numbers after converting them to string.
Why don't you just parse the text to integer and format it with a proper way for display.
Here is a example you should take a look
I would like to thank everyone else for their help with suggestions on how to fix this, and I am sure that they are all possible. However, I found that the best way, was to still convert the BigInteger to string, but not to add whitespace.
If the string's length was less than 6 I left it as it was and simply added whitespace for looks. If it was longer then 6, I took the first 1, 2 or 3 numbers depending on the Mod of the string's length and used them as actual numbers to show at the start (1 Million, 34 Billion, 124 Quadrillion, etc).
This was then followed by seeing how long the remaining string was, and simply adding more string to the display text if it was longer then a certain amount.
If anyone needs clarification of this, please do not hesitate to ask me! Here is the link to the pastebin - http://pastebin.com/3X681UkG
Good luck!
Example implementation that rounds numbers over one thousand to one significant figure.
Optionally, groups of three digits may be separated by comma or space.
private final static String[] illions = {
"m", "b", "tr", "quadr", "quint", "sext", "sept", "oct", "non", "dec",
"undec", "duodec", "tredec", "quattuordec", "quindec", "sexdec",
"septendec", "octodec", "novemdec", "vigint", "unvigint", "duovigint",
"trevigint", "quattuorvigint", "quinvigint", "sexvigint", "septenvigint",
"octovigint", "novemvigint", "trigint", "untrigint", "duotrigint"
};
private static String approximate( String n ) {
String approx = n;
if ( n != null && n.matches( "^\\d{1,3}[\\s,]?(\\d{3}[\\s,]?)*\\d{3}$" ) ) {
n = n.replaceAll( "[\\s,]", "" );
int i = n.length() + 2;
if ( i < 105 ) {
int rnd = (int) Math.round( Double.parseDouble( n.substring( 0, 2 ) ) / 10 )
* (int) Math.pow(10, i % 3);
n = i > 8 ? illions[ i / 3 - 3 ] + "illion" : "thousand";
approx = rnd + " " + n;
}
}
return approx;
}
Test
System.out.printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s",
approximate("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"), // "1000 duotrigintillion"
approximate("4857476486598746598743265987426598724365987265987324598726598734625987564987456"), // "5 quinvigintillion"
approximate("56843584275874587243582837465847326554"), // "60 undecillion"
approximate("1 345 678 910 111 213"), // "1 quadrillion"
approximate("47,648,658,437,651"), // "50 trillion"
approximate("9 891 011 123"), // "10 billion"
approximate("687654321"), // "700 million"
approximate("32 456 999"), // "30 million"
approximate("2,678,910"), // "3 million"
approximate("1 234 567"), // "1 million"
approximate("123456"), // "100 thousand"
approximate("17,654"), // "20 thousand"
approximate("8765"), // "9 thousand"
approximate("654") // "654"
);
I would just simply count digits. rough code from scratch:
String result = "";
Pattern pattern = Pattern.compile("[\\s0-9]+");
Matcher matcher = pattern.matcher(t);
int index = 0;
while (matcher.find()) {
int newIndex = matcher.start();
result += t.substring(index, newIndex);
result += convert(matcher.group());
index = matcher.end() + 1;
}
result += t.substring(index, t.length() - 1);
private String convert(String uglyNumber) {
// get rid of whitespaces
String number = uglyNumber.replace("\\s", "");
// simply count digits
if( 6 < number.length() && number.length() <= 9 ) {
return "million";
} else if( 9 < number.length() && number.length() <= 12 ) {
return "million";
} else ...
return ulgyNumber;
}
if numbers are more compilcated than simple mix of digits and whitespaces, you may want to have a look for this regex site: