How to get the decimal places of a number in Flutter/Dart - flutter

I wondered if there is a function to provide clean solution to getting the amount of decimal places or checking if a number has decimal places in Dart/Flutter?

Here is how I've done it:
static int getDecimalPlaces(var number) {
int decimals = 0;
List<String> substr = number.toString().split('.');
if (substr.length > 0) decimals = int.tryParse(substr[1]);
return decimals;
}
static bool hasDecimalPlaces(var number) {
String <List> substr = number.toString().split('.');
return (substr.length > 1);
}

You should check if it contains it at all.
This returns how many decimals you got:
getNumberOfDecimals(String number) {
if (number.contains('.')) {
return number.substring(number.indexOf('.')+1).length;
}
return 0;
}

A bit more elegant answer. You split the string at the decimal point and check the length of the 2nd string.
getNumberOfDecimals(String number) {
if (number.contains('.')) {
return number.split(".")[1].length;
}
return 0;
}

Related

How to hide decimal value when it is = 0

I am currently trying to render the price value of products using a widget in Flutter.
To do so, I pass the state and render it in the argument from the corresponding widget.
What I need to achieve is to hide the 2 decimals of my Double type priceValue and show them if they are != to 0.
Like so, if state.priceValue = 12.00 $ => should show 12
if state.priceValue = 12.30 $ => should show 12.30
String removeZero(double money) {
var response = money.toString();
if (money.toString().split(".").length > 0) {
var decmialPoint = money.toString().split(".")[1];
if (decmialPoint == "0") {
response = response.split(".0").join("");
}
if (decmialPoint == "00") {
response = response.split(".00").join("");
}
}
return response;
}
Edit: I added to check if the string contains a decimal point or not to avoid index out of bounds issue
Try this:
String price = "12.00$"
print(price.replaceAll(".00", ""));
Or refer to this: How to remove trailing zeros using Dart
double num = 12.50; // 12.5
double num2 = 12.0; // 12
double num3 = 1000; // 1000
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
String s = num.toString().replaceAll(regex, '');
But the second option will remove all trailing zeros so 12.30 will be 12.3 instead
Hello you could use an extension like that:
extension myExtension on double{
String get toStringV2{
final intPart = truncate();
if(this-intPart ==0){
return '$intPart';
}else{
return '$this';
}
}
}
To use the extension:
void main() {
double numberWithDecimals = 10.8;
double numberWithoutDecimals = 10.00;
//print
print(numberWithDecimals.toStringV2);
print(numberWithoutDecimals.toStringV2);
}

12.0 can't be identified as double nor int or numeric in flutter

I have this problem with dart. I created a simple calculator. If the result if a calculation is equal to, for example, -12.9 or 12.9. The app gives the correct answer and no error. But, if the answer given is 12.0 or -12.0, the app crashes. Why is that? I created a function to check if the string is an int or a double. It returns false.
bool isDouble(String number) {
try {
num n = num.parse(number);
if (n % 1 == 0) {
return false;
} else {
return true;
}
} catch (e) {
return false;
}
}
For the numeric, I used the isNumeric function in dart. Please help me.
As Riwen mentioned, any whole number % 1 is 0, even if it's a float. You can check the type of a variable with .runtimeType. I think when you parse the string to num, it automatically converts whole numbers to int, so you cant just check if runtimeType == "double". Also, to remove decimal values, you can just use .floor(), which will round down and convert the variable to an int.
This function seems to work:
bool isDouble(String number) {
if (int.tryParse(number) == null){
if (double.parse(number).isFinite) return true;
}
return false;
}

How to fix both Found 'DD'-anomaly and only one return statement

I have some difficulties when fixing PMD warnings, this was my simplified method:
public String rank(String keyword, int pageSize, int totalPage)
{
String result = "0"; // A: DataflowAnomalyAnalysis: Found 'DD'-anomaly for variable 'result'
if (isNotBlank(keyword))
{
boolean find = false; // B: DataflowAnomalyAnalysis: Found 'DD'-anomaly for variable 'find'
for (int page = 1; page < totalPage; page++)
{
int rank = getRank(keyword, pageSize, totalPage);
if (rank != 0)
{
find = true; // B(1)
result = String.valueOf(rank); // A(1)
break;
}
}
if (!find)
{
result = format("{0}+", totalPage * pageSize - 1); // A(2)
}
}
return result;
}
I tried this and got "OnlyOneReturn" warnings:
public String rank(String keyword, int pageSize, int totalPage)
{
if (isNotBlank(keyword))
{
for (int page = 1; page < totalPage; page++)
{
int rank = getRank(keyword, pageSize, totalPage);
if (rank != 0)
{
return String.valueOf(rank); // OnlyOneReturn
}
}
return format("{0}+", totalPage * pageSize - 1); // OnlyOneReturn
}
return "0";
}
How do I have to write this code please?
A 'DD'-anomaly an a dataflow analysis tells you that you assign a variable more than once without using it between the assignments. So all but the last assignment are unnecessary. It usually indicates that you didn't separate your scenarios properly. In your case you have three scenarios:
If the keyword is blank then the return value is "0".
Otherwise loop through all pages and if getRank() returns a rank other than zero then this is the return value.
Otherwise the return value is "totalPage * pageSize - 1+"
If you implement those scenarios one by one you end up with a method that has not any dataflow or other PMD issues:
public String rank(String keyword, int pageSize, int totalPage) {
String result;
if (isNotBlank(keyword)) {
result = "0";
} else {
int rank = 0;
for (int page = 1; page < totalPage && rank == 0; page++) {
rank = getRank(keyword, pageSize, totalPage);
}
if (rank != 0) {
result = String.valueOf(rank);
} else {
result = format("{0}+", totalPage * pageSize - 1);
}
}
return result;
}
If you take a closer look at the for loop you see that page is only used for looping. It is not used inside the loop. This indicates that the for loop is probably not necessary. getRank(keyword, pageSize, totalPage) should always return the same value as its arguments never change during the loop. So it might be enough to call getRank(...) just once.

Convert an arbitrarily long hexadecimal string to a number in Dart?

I need to convert a string of 8-character hexadecimal substrings into a list of integers.
For example, I might have the string
001479B70054DB6E001475B3
which consists of the following substrings
001479B7 // 1341879 decimal
0054DB6E // 5561198 decimal
001475B3 // 1340851 decimal
I'm currently using convert.hex to first convert the strings into a list of 4 integers (because convert.hex only handles parsing 2-character hex strings) and then adding/multiplying those up:
String tmp;
for(int i=0; i<=myHexString.length-8; i+=8){
tmp = myHexString.substring(i, i+8);
List<int> ints = hex.decode(tmp);
int dec = ints[3]+(ints[2]*256+(ints[1]*65536)+(ints[0]*16777216));
}
Is there a more efficient way to do this?
You can use int.parse('001479B7', radix: 16);
https://api.dartlang.org/stable/2.4.1/dart-core/int/parse.html
so your code will look like this :
void main() {
final fullString = '001479B70054DB6E001475B3';
for (int i = 0; i <= fullString.length - 8; i += 8) {
final hex = fullString.substring(i, i + 8);
final number = int.parse(hex, radix: 16);
print(number);
}
}
Since my Hex string came smaller than 8 elements of Byte, I did this.
String dumpHexToString(List<int> data) {
StringBuffer sb = StringBuffer();
data.forEach((f) {
sb.write(f.toRadixString(16).padLeft(2, '0'));
sb.write(" ");
});
return sb.toString();
}
String conertHexDecimal(String str1) {
final fullString = str1;
int number = 0;
for (int i = 0; i <= fullString.length - 8; i += 8) {
final hex = fullString.substring(i, i + 8);
number = int.parse(hex, radix: 16);
print(number);
}
return number.toString();
}
void executarConersao(Uint8List data){
String conersorHexDeVar = dumpHexToString(data);
conersorHexDeVar = conersorHexDeVar
.substring(3, conersorHexDeVar.length)
.replaceAll(' ', '')
.padLeft(8, '0');
conersorHexDeVar = conertHexDecimal(conersorHexDeVar);
print('data $conersorHexDeVar');
}
For anyone who wants to convert hexadecimal numbers to 2's component, Dart / Flutter has a builtin method - .toSigned(int):
var testConversion = 0xC1.toSigned(8);
print("This is the result: " + testConversion.toString()); // prints -63

Issue with getting 2 chars from string using indexer

I am facing an issue in reading char values.
See my program below. I want to evaluate an infix expression.
As you can see I want to read '10' , '*', '20' and then use them...but if I use string indexer s[0] will be '1' and not '10' and hence I am not able to get the expected result.
Can you guys suggest me something? Code is in c#
class Program
{
static void Main(string[] args)
{
string infix = "10*2+20-20+3";
float result = EvaluateInfix(infix);
Console.WriteLine(result);
Console.ReadKey();
}
public static float EvaluateInfix(string s)
{
Stack<float> operand = new Stack<float>();
Stack<char> operator1 = new Stack<char>();
int len = s.Length;
for (int i = 0; i < len; i++)
{
if (isOperator(s[i])) // I am having an issue here as s[i] gives each character and I want the number 10
operator1.Push(s[i]);
else
{
operand.Push(s[i]);
if (operand.Count == 2)
Compute(operand, operator1);
}
}
return operand.Pop();
}
public static void Compute(Stack<float> operand, Stack<char> operator1)
{
float operand1 = operand.Pop();
float operand2 = operand.Pop();
char op = operator1.Pop();
if (op == '+')
operand.Push(operand1 + operand2);
else
if(op=='-')
operand.Push(operand1 - operand2);
else
if(op=='*')
operand.Push(operand1 * operand2);
else
if(op=='/')
operand.Push(operand1 / operand2);
}
public static bool isOperator(char c)
{
bool result = false;
if (c == '+' || c == '-' || c == '*' || c == '/')
result = true;
return result;
}
}
}
You'll need to split the string - which means working out exactly how you want to split the string. I suspect you'll find Regex.Split to be the most appropriate splitting tool in this case, as you're dealing with patterns. Alternatively, you may want to write your own splitting routine.
Do you only need to deal with integers and operators? How about whitespace? Brackets? Leading negative numbers? Multiplication by negative numbers (e.g. "3*-5")?
Store the numerical value in a variable, and push that when you encounter an operator or the end of the string:
int num = 0;
foreach (char c in s) {
if (isOperator(c)) {
if (num != 0) {
operand.Push(num);
num = 0;
}
operator1.Push(c);
if (operand.Count == 2) {
Compute(operand, operator1);
}
} else {
num = num * 10 + (int)(c - '0');
}
}
if (num != 0) {
operand.Push(num);
}