I want to convert my string value to int16 and only show 2 decimal places. I have tried the below, but it throws an error as my string value is not actually converted?
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string number1 = "1234.00011";
Console.Write(number1);
Console.WriteLine();
string r = String.Format("{0:F2}", number1);
Console.Write(Convert.ToInt16(r));
}
}
}
EDIT
The line that throws the error is
Console.Write(Convert.ToInt16(r));
And the error is
An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll
Additional information: Input string was not in a correct format.
Your call to string.Format is using a floating point format specifier and providing a string argument. These are mutually incompatible. As a result, the string argument is inserted as-is into the result, and stored in r, so that you don't get the desired two-digit rounding you're looking for.
What you likely want to do is something like this:
static void Main(string[] args)
{
string number1 = "1234.00011";
Console.Write(number1);
Console.WriteLine();
var r1 = float.Parse(number1);
string r = String.Format("{0:F2}", r1);
Console.WriteLine(r);
Console.Write((int)r1);
Console.ReadKey();
}
In my tests, it produces the following output:
1234.00011
1234.00
1234
Note that the second line has the desired rounding, because we provided a floating point value to string.Format, so that {0:F2} would work properly. The third line has no decimal places, because we used a direct cast and includes no floating point digits whatsoever.
Related
I have a string coming from PC through serial to a microcontroller (Arduino), e.g.:
"HDD: 55 - CPU: 12.6 - Weather: Cloudy [...] $";
by this function I found:
String inputStringPC = "";
boolean stringCompletePC = false;
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputStringPC += inChar;
if (inChar == '$') // end marker of the string
{
stringCompletePC = true;
}
}
}
I would like to extract the first number of it after the word HDD, CPU and also get the string after Weather (ie "cloudy"); my thinking is something like that:
int HDD = <function that does that>(Keyword HDD);
double CPU = <function that does that>(Keyword CPU);
char Weather[] = <function that does that>(Keyword Weather);
What is the right function to do that?
I looked into inputStringSerial.indexOf("HDD") but I am still a learner to properly understand what it does and don't know if theres a better function.
My approach yielded some syntax errors and confused me with the difference in usage between "String inputStringSerial" (class?) and "char inputStringSerial[]" (variable?). When I do 'string inputStringSerial = "";' PlatformIO complains that "string" is undefined. Any help to understand its usage here is greatly appreciated.
Thanks a bunch.
The String class provides member functions to search and copy the contents of the String. That class and all its member functions are documented in the Arduino Reference:
https://www.arduino.cc/reference/tr/language/variables/data-types/stringobject/
The other way a list of characters can be represented is a char array, confusingly also called a string or cstring. The functions to search and copy the contents of a char array are documented at
http://www.cplusplus.com/reference/cstring/
Here is a simple Sketch that copies and prints the value of the Weather field using a String object. Use this same pattern - with different head and terminator values - to copy the string values of the other fields.
Once you have the string values of HDD and CPU, you'll need to call functions to convert those string values into int and float values. See the String member functions toInt() and toFloat() at
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/
or the char array functions atoi() and atof() at
http://www.cplusplus.com/reference/cstdlib/atoi/?kw=atoi
String inputStringPC = "HDD: 55 - CPU: 12.6 - Weather: Cloudy [...] $";
const char headWeather[] = "Weather: "; // the prefix of the weather value
const char dashTerminator[] = " -"; // one possible suffix of a value
const char dollarTerminator[] = " $"; // the other possible suffix of a value
void setup() {
int firstIndex; // index into inputStringPC of the first char of the value
int lastIndex; // index just past the last character of the value
Serial.begin(9600);
// find the Weather field and copy its string value.
// Use similar code to copy the values of the other fields.
// NOTE: This code contains no error checking for unexpected input values.
firstIndex = inputStringPC.indexOf(headWeather);
firstIndex += strlen(headWeather); // firstIndex is now the index of the char just past the head.
lastIndex = inputStringPC.indexOf(dollarTerminator, firstIndex);
String value = inputStringPC.substring(firstIndex, lastIndex);
Serial.print("Weather value = '");
Serial.print(value);
Serial.println("'");
}
void loop() {
// put your main code here, to run repeatedly:
}
When run on an Arduio Uno, this Sketch produces:
Weather value = 'Cloudy [...]'
This yields 127
double middle = 255 / 2
While this yields 127.5
Double middle = 255 / 2
Meanwhile this yields 127.5 as well
double middle = (255 / 2) as double
I know that Groovy operates with BigDecimal per default, but to me this is a Huuge bug! How can this be?
This actually has nothing to do with BigDecimals, but rather with the type coercion from primitive integer to the primitive double. This problem is caused by the Groovy compiler and the (most probably) incorrect bytecode it produces. Take a look at the following bytecode representation of the first case. The following Groovy code:
void ex1() {
double x = 255 / 2
println x
}
gets compiled to a bytecode that can be represented as:
public void ex1() {
CallSite[] var1 = $getCallSiteArray();
double x = 0.0D;
if (BytecodeInterface8.isOrigInt() && BytecodeInterface8.isOrigD() && !__$stMC && !BytecodeInterface8.disabledStandardMetaClass()) {
int var5 = 255 / 2;
x = (double)var5;
} else {
Object var4 = var1[5].call(255, 2);
x = DefaultTypeTransformation.doubleUnbox(var4);
}
var1[6].callCurrent(this, x);
}
It shows that in this case, it is not possible to get 127.5 as a result, because the result of 255 / 2 expression is stored in the variable of type int. It feels like this is an example of inconsistent behavior because here is what the bytecode of the method that uses Double looks like:
public void ex2() {
CallSite[] var1 = $getCallSiteArray();
Double x = null;
if (BytecodeInterface8.isOrigInt() && !__$stMC && !BytecodeInterface8.disabledStandardMetaClass()) {
Object var4 = var1[8].call(255, 2);
x = (Double)ScriptBytecodeAdapter.castToType(var4, Double.class);
} else {
Object var3 = var1[7].call(255, 2);
x = (Double)ScriptBytecodeAdapter.castToType(var3, Double.class);
}
var1[9].callCurrent(this, x);
}
The main problem with this use case is that adding #TypeChecked does not prevent you from making this mistake - compilation passes and the incorrect result is returned. However, when we add #TypeChecked annotation to the method that uses Double the compilation error is thrown. Adding #CompileStatic solves the problem.
I've run some tests and I can confirm that this problem exists in the recent 2.5.6, as well as 3.0.0-alpha-4 versions. I've created a bug report in the Groovy JIRA project. Thanks for finding and reporting the problem!
UPDATE: Java does the same
It seems like this is not a Groovy bug - this is how Java does things as well. In Java, you can store a result of a division of two ints in the double variable, but you will get nothing else than an integer cast to the double. With {{Double}} type things are different in terms of the syntax but pretty similar in terms of the bytecode. With {{Double}} you need to explicitly cast at least one part of the equation to the {{double}} type, which results in the bytecode that casts both integers to the {{double}}. Consider the following example in Java:
final class IntDivEx {
static double div(int a, int b) {
return a / b;
}
static Double div2(int a, int b) {
return a / (double) b;
}
public static void main(String[] args) {
System.out.println(div(255,2));
System.out.println(div2(255,2));
}
}
When you run it you get:
127.0
127.5
Now, if you take a look at the bytecode it creates, you will see something like this:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
final class IntDivEx {
IntDivEx() {
}
static double div(int a, int b) {
return (double)(a / b);
}
static Double div2(int a, int b) {
return (double)a / (double)b;
}
public static void main(String[] args) {
System.out.println(div(255, 2));
System.out.println(div2(255, 2));
}
}
The only difference (in terms of the syntax) between Groovy and Java is that Groovy allows you to implicitly cast an integer to Double, and that is why
Double x = 255 / 2
is the correct statement in Groovy, while Java, in this case, fails during the compilation with the following error:
Error:(10, 18) java: incompatible types: int cannot be converted to java.lang.Double
That is why in Java you need to use casting when you assign from integer to Double.
I am very new to java, and this is homework. Any direction would be appreciated.
The assignment is to read an external text file and then parse that file to produce a new file.
The external file looks something like this:
2 //number of lines in the file
3,+,4,*,2,-.
5,*,2,T,1,+
I have to read this file and produce an output that takes the preceding int value and prints the following character (skipping the comma). So the output would look like this:
+++****--
*****TT+
I have tried to setup my code using two methods. The first to read the external file (passed as a parameter) which, as long as there is a next line, will call a second method, processLine, to parse the line. This is where I am lost. I can't figure out how this method should be structured so it reads the line and interprets the token values as either ints or chars, and then executes code based on those values.
I am only able to use what we have covered in class, so no external libraries, just the basics.
public static void numToImageRep(File input, File output) //rcv file
throws FileNotFoundException {
Scanner read = new Scanner(input);
while(read.hasNextLine()){ //read file line by line
String data = read.nextLine();
processLine(data); //pass line for processing
}
}
public static void processLine(String text){ //incomplete, all falls apart here.
Scanner process = new Scanner(text);
while(process.hasNext()){
if(process.hasNextInt()){
int multi = process.nextInt();
}
if(process.hasNext()==','){
}
}
this method can be a simple example that can do the job:
public static String processLine(String text){
String result = "";
String[] splitted = text.split(",");
int remaining = 0;
for(int i=0;i<splitted.length;i+=2)
{
remaining = (Integer.parseInt(splitted[i]));
while( remaining-- >0)
result += splitted[i+1];
}
return result;
}
I put a number in EditText line and it counts a double value in another.
But the double value of 4.8 should be 9.6 and not 9.6000000381469727.
I know it is normal for float but I would like to cut the amount of decimal numbers to 4. I'm not sure how to do this in my code.
private void calc(double number, operation input) {
double a = 0;
switch (input) {
case a:
valuedouble.setText(valuecount(number));
private String valueucount(double input) {
return Double.toString( input*2 );
}
Thanks for reply.
You can use the following command (format strings)
String.format("%.4f", number);
See this site for a complete list of format strings.
I'm parsing a file that has integer values using commas to separate thousands.
String s = "1,503"
Integer i = new Integer(s)
does not work, throws a parse exception. Is there an easy way to parse this?
Thanks
A slightly more groovy method might be;
int a = java.text.NumberFormat.instance.parse( '1,234' )
But this will use the default locale
Use NumberFormat instead. For example, in Java:
import java.util.*;
import java.text.*;
public class Test {
public static void main(String args[]) throws ParseException {
NumberFormat format = NumberFormat.getIntegerInstance(Locale.US);
Long parsed = (Long) format.parse("1,234");
System.out.println(parsed);
}
}
(You can then get the integer value from the Long, of course.)
I've explicitly specified Locale.US to guarantee that comma is used as the thousands separator; you may want to use a different locale if the input can vary.