-1

Ok this should be a rather simple problem but I just can't get this right. I have a cumulative sum that's returning a double. These represent percents and it should never be 0.0.. so I figured use d % 1 to keep things under 1. Works fine for 2.13 which becomes 0.13, or 2.98 becomes 0.98, however 3.0 becomes 0.0 not 1.0 (100%)..

I'm obviously doing something fundamentally wrong here? or perhaps I just cheat and say if 0 then 1?

Thanks

wizard_draziw
  • 505
  • 1
  • 5
  • 17
  • What does 2.0 give you? I don't completely understand what you are doing. As a general rule, use BigDecimal when doing math in Java. – jmf1205 Mar 19 '15 at 05:36
  • 2 % 1 = 0.. it's a running list of decimals but every time it hits a whole number I want it to result in 1 so 1, 2, 3,..,n = 1, 1, 1, 1. Or 1.1, 2.1,...,n.1 = 0.1, 0.1 etc – wizard_draziw Mar 19 '15 at 05:49
  • do you want `0 % 1` => `1` ? – Peter Lawrey Mar 19 '15 at 06:14
  • 1
    Your question is lacking a clear specification: why do you accept a function that is not monotonous ? (like `f(1.98) > f(2.13)`). IMO this is fundamentally wrong. –  Mar 19 '15 at 10:12

4 Answers4

2

% is the Modulus operator

From wikipedia:

"In computing, the modulo operation finds the remainder after division of one number by another (sometimes called modulus)"

In other words 3 modulo 1 = 0 because the remainder after dividing 3 by 1 is zero.

Astra Bear
  • 2,646
  • 1
  • 20
  • 27
1

The modulus is behaving as expected - there is no remainder when dividing 3.0 by 1.0.

If you want to handle the special case of no remainder:

d %= 1.0
d = d == 0.0 ? 1.0 : d;
Bohemian
  • 412,405
  • 93
  • 575
  • 722
1
  1. when cumulative (percentage) sum hits 1.0 (100%) boundary

    • why to set it to sum=sum%1 ?
    • if the meaning is a percentage of some operation then should not it be still 1.0 ?
    • so while summing I would do something like this instead:

      for (...)
       {
       // some stuff of yours
       sum+=...;
       if (sum>1.0) sum=1.0;
       }
      
  2. if you still need the modulus 1 then you can exploit floor

    • but that operation does not give any sense to me (other than pulsing progress bar)
    • unless the sum is used for something else then I think

      for (...)
       {
       // some stuff of yours
       sum+=...;             
       if (sum>1.0) sum-=floor(sum);
       }
      
    • if your sum can be negative then handle negative values separately with ceil

    • if the 1.0 is also not wanted then ignore the if and sub the floor(sum) always
  3. if you know the target sum

    • if sum is representing progress state
    • and you know the last value (entire sum)
    • then the percentage=sum/whole_sum);
Spektre
  • 49,595
  • 11
  • 110
  • 380
1

What about x/(x+a) or 1-exp(-ax) ?

  • @YvesDaoust and very nice if target sum is known just approximately :) didn't think of that (+1) – Spektre Mar 19 '15 at 18:40