3

I have two variables, float a and float b. I want to set a boolean inRange variable to true only if both a and b are between 0.0f and 1.0f. I could just do this:

boolean inRange = a >= 0.0f && a <= 1.0f && b >= 0.0f && b <= 1.0f;

But I'm wondering if there is a nicer method of checking this. Is there a cleaner way, or possibly more efficient way to do this?

name
  • 362
  • 2
  • 12
  • 2
    what is wrong with that? – assembler Aug 04 '17 at 20:48
  • @assembler As the question states, I would prefer a more clean, more readable solution. – name Aug 04 '17 at 20:49
  • 1
    @name Unless you're in a particular hurry. I'd recommend you leave a bit more time before accepting an answer. There may be better answers to come. – ᴇʟᴇvᴀтᴇ Aug 04 '17 at 21:04
  • You shouldn't worry about efficiency unless you've *measured* and found this to be a real drag (unlikely because any I/O will swamp it). However, for fun, you might be able to tune it to be more efficient by reordering the conditions putting "most likely to fail" first to take maximum advantage of shortcutting. – ᴇʟᴇvᴀтᴇ Aug 04 '17 at 21:28

3 Answers3

6

Create a method for it (There is a reason functions are the oldest type of code organization, they work!)

if(inRange(a) && inRange(b))
   ...

This can be modified by your needs of course, but in general having another method with a good name is a fantastic solution. Also you're not distributing 1.0/0.0 constants throughout your code.

A more general purpose answer would be to create a RangeValidation class (Assuming you have other Validation classes)

RangeValidation criticalRange=new RangeValidation(0.0, 1.0);

criticalRange.validate(a);
criticalRange.validate(b);

This pattern is a bit more wordy at first but it can be used as part of a validation system--Imagine many different types of Validation objects that can all be run against a value with a simple allValidations.validate(a). Not very valuable with scalars, but the pattern could be used to validate more complex objects

Bill K
  • 62,186
  • 18
  • 105
  • 157
  • I don't find `inRange` descriptive enough. You'd have to look into the function to know what range it means. – ᴇʟᴇvᴀтᴇ Aug 04 '17 at 20:59
  • And the `RangeValidation` class could simply be called `Range`. The method could then be `range.contains(x)`. – ᴇʟᴇvᴀтᴇ Aug 04 '17 at 21:00
  • I agree. I was trying to find a business logic example but I couldn't. How about isPercentage? – Bill K Aug 04 '17 at 21:01
  • `isBetweenZeroAndOneInclusive(double x)` – ᴇʟᴇvᴀтᴇ Aug 04 '17 at 21:02
  • Good point. I would be more likely to attach a business logic name, for instance if the validation was "age must be>=21" I might call it isDrinkingAge so I don't have to change the name for different countries, just the implementation. – Bill K Aug 04 '17 at 21:12
  • Instead of creating your own set of Validation classes you could use or extend pre-existing Matchers from Hamcrest. https://stackoverflow.com/questions/12783335/hamcrest-number-comparison-using-between – ᴇʟᴇvᴀтᴇ Aug 04 '17 at 21:16
  • Absolutely, but it's easier just to describe the type of functionality here rather than refer people to other tools. – Bill K Aug 04 '17 at 21:19
1

There's not really a more efficient way to accomplish this, but in my opinion it could definitely be "cleaner". One way to accomplish this would be to define constants for your bounds. Secondly, having a secondary method to call into to check for a single value improves readability in your primary method. See my example below

public class YourClass {
    private static final float FLOOR = 0.0f;
    private static final float CEILING = 1.0f;

    public boolean inRange(float a, float b) {
        return inRange(a) && inRange(b);
    }

    private boolean inRange(float x) {
        return x > FLOOR && x < CEILING;
    }
}
Brandon Laidig
  • 430
  • 2
  • 14
0

Create a method :

public boolean inRangeMethod(float a){
                return (a>=0.0f && a<=1.0f);
            }

After:

boolean inRange = false;
inRange = inRangeMethod(a) && inRangeMethod(b);