28

How do I check if a value is a whole number (integer) or contains a decimal? In Javascript we have isInteger but I couldn't find the equivalent in Dart.

We seem to have checks for isEven, isOdd, isFinite, isInfinite, isNaN and isNegative but no isInteger?

1
  • Still no valid answers that actually work in Flutter. Commented Sep 19, 2019 at 13:50

6 Answers 6

52

Dart numbers (the type num) are either integers (type int) or doubles (type double).

It is easy to check if a number is an int, just do value is int.

The slightly harder task is to check whether a double value has an integer value, or no fractional part. There is no simple function answering that, but you can do value == value.roundToDouble(). This removes any fractional part from the double value and compares it to the original value. If they are the same, then there was no fractional part.

So, a helper function could be:

bool isInteger(num value) => 
    value is int || value == value.roundToDouble();

I use roundToDouble() instead of just round() because the latter would also convert the value to an integer, which may give a different value for large double values.

Another test for a double having an integer value could be value % 1.0 == 0.0, but it's not more readable, unlikely to be more efficient, and even though it does actually work, I had to check what % 1.0 does for double.infinity (it gives NaN) before I could trust it.

Sign up to request clarification or add additional context in comments.

8 Comments

This actually does work, unlike the other answers. Although I would think this would be part of Dart. Since it has less useful functions like isOdd, is Even etc which are even simpler to check.
@lrn Would using truncateToDouble not be slightly simpler than using roundToDouble?
I'm surprised that there does not seem to be an equivalent to C's modf to extract the integral and fractional parts of a double.
It shouldn't matter which of truncateToDouble, roundToDouble, floorToDouble or ceilToDouble you use, except for performance. It does seem that roundToDouble is slower than the other three on the VM, and both roundToDouble and truncateToDouble are slower when compiled to JS and run in Chrome. Neither are so bad I'd care unless I know it's a bottleneck for my app (and then I'd check other browsers too).
If the goal is to detect non-fractional num values (which it is here), then is int is correct, and on the web, it's all you need (well, if you want to include the infinite values, otherwise you may need to add && x.isFInite). The code above works for the current Dart number implementations, and if anything changes, it's likely going to be the web getting real integers (as a feature in JS or by or compiling to WASM instead of JS), and then it'll still be correct. It's true that you should not use is int to deduce that the value is not a double.
|
25

Use the modulo operator %:

  bool isInteger(num value) => (value % 1) == 0;

Same as an extension method:

  extension NumExtensions on num {
    bool get isInt => (this % 1) == 0;
  }

Usage:

  double d = 2.6;
  double d2 = 2.0;
  int i = 2;
  print(d.isInt); // returns false
  print(d2.isInt); // returns true
  print(i.isInt); // returns true

1 Comment

I am not sure about the speed of this compared to others, but I find the modulo operator way of doing it easier to understand. I think it comes to preference. I would however, avoid using an extension method on a native object as extensions can cause more confusion and are difficult to determine where they come from. I would instead create a helper class for working with numbers called something like Math
6
void main() {
  int a = 10;
  print(a is int); // Prints true
}

OR

void main() {
  dynamic a = 10;
  print(a is int ? a/10 :"Not an int"); // Prints 1
}

4 Comments

Actually it doesn't seem to work? print((2 + 2) is int); = true, print((2 / 2) is int); = false ??
print((2 / 2) is int); and print((2 + 2) is int); both prints true
I'm not getting that in Flutter, which version of Dart is that? Are you checking it in Flutter?
I think you should remove your answer because it's confirmed that it does not work in Dart. It does not verify a whole number so it's misleading to others seeing your answer. It does work in Dartpad because Dartpad compiles to javascript, but it does not work in actual Dart code like we see in Flutter.
3

I did it like this and works just fine:

bool _isInteger(double value) => value == value.toInt();

Method toInt() drops the decimal part, so if after dropping this part nothing changed, it means it is an integer.

Comments

1

I just make two extension method (in DART), Here i get true if given number integer(whole) or false if given number if double(decimal).

Here isInteger method will give boolean value and getDoubleOrInt method will give String value which is integer or two decimal precise decimal string format value.

Extension Method

extension OnNumber on num {
  String get getDoubleOrInt {
    if (toString().split('.').length > 1) {
      if (int.parse(toString().split('.').elementAt(1)) > 0) {
        return toDouble().toStringAsFixed(2);
      } else {
        return toInt().toString();
      }
    } else {
      return toInt().toString();
    }
  }

  bool get isInteger {
    if (toString().split('.').length > 1) {
      if (int.parse(toString().split('.').elementAt(1)) > 0) {
        return false;
      } else {
        return true;
      }
    } else {
      return true;
    }
  }
}

Application Example

void main() {
  double x = 3.5999;
  
  print(x.isInteger); // false
  print(x.getDoubleOrInt); // 3.60
  
  int y = 123; 
  
  print(y.isInteger);  // true
  print(y.getDoubleOrInt); // 123
  
}

UPDATE

In above code work fine. But not work in particular below case

->  3.000/3.0014/3.0099 it give return 3.00 

-> i want with two digit of approximation for digit number and if it is like 3.00 or 5.00 then it is Integer and now  i need to convert this in to integer (like 3 or 5)

Below Extension is more accurate

extension OnNumber on num {
  String get getDoubleOrInt {
    if (toString().split('.').length > 1) {
      if (int.parse(toString().split('.').elementAt(1)) > 0) {
        final temp = toDouble().toStringAsFixed(2);
        final number = double.parse(temp);
        if (number.isInteger) {
          return number.toInt().toString();
        } else {
          return number.toString();
        }
      } else {
        return double.parse('$this').toInt().toString();
      }
    } else {
     
      return int.parse('$this').toInt().toString();
    }
  }

  bool get isInteger {
    if (toString().split('.').length > 1) {
      if (int.parse(toString().split('.').elementAt(1)) > 0) {
        return false;
      } else {
        return true;
      }
    } else {
      return true;
    }
  }
}

Hope you like this two method.

Comments

0

To check the datatype of any variable in Dart, you can make use of the keyword is. For instance :

void main() {
     int x = 10;
     double y = 20;
     checkType(x, y);
    }

void checkType(dynamic x, dynamic y) {
  if (x is int) {
    print(x);
  } else {
    print(y);
  }
}

The code above will print 10 since the variable x inside the main function is an Integer Data type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.