I am trying to divide two time durations (java.time.Duration) and to perform that there are two methods
java.time.Duration#dividedBy(long) which returns an object of type Duration itself but due to some API restrictions I can not use this version.
java.time.Duraiton#dividedBy(Duration) which returns a long and returns number of times one duration occurs within other duration but here we lose the precision as it does not care about the remainder.
Is there any way out to perform this division and get the result with remainder.
Duration.ofHours(1).dividedBy(7L); //returns 8M34.28571 seconds
Duration.ofHours(1).dividedBy(Duration.ofSeconds(7L)) // returns 514 seconds
I have a restriction not to use the first way. Can I get the results using some other way?
EDIT: (from comments) I am not allowed to convert a Duration instance to an ordinal value, e.g. milliseconds.
Convert to milliseconds/nanoseconds, then divide their ordinal value(s), then create a new Duration object from the result.
When the easy ways are forbidden, you can of course do it the more cumbersome way. The following is similar to how we learned to do division by hand in school.
Duration dividend = Duration.ofHours(1);
long divisor = 7;
long minutes = dividend.toMinutes() / divisor;
dividend = dividend.minusMinutes(minutes * divisor);
long seconds = dividend.toSeconds() / divisor;
dividend = dividend.minusSeconds(seconds * divisor);
long nanoseconds = dividend.toNanos() / divisor;
Duration result = Duration.ofMinutes(minutes)
.plusSeconds(seconds)
.plusNanos(nanoseconds);
System.out.println(result);
Result output:
PT8M34.285714285S
Your requirements are not that precise, so I can’t be sure I haven’t used a forbidden method, though.
Related
I'm reading Java: The Complete Reference by Herbert Schildt right now and here is one thing that is not really clear for me. In the chapter about Integers it says that the long type should be used when big, whole numbers are needed. The code example from the book:
// Compute distance light travels using long variables
class Light {
public static void main(String args[]) {
int lightspeed;
long days;
long seconds;
long distance;
// approximate speed of light in miles per second
lightspeed = 18600;
days = 1000; // specify number of days here
seconds = days * 24 * 60 * 60; // convert to seconds
distance = lightspeed * seconds; // compute distance
System.out.print("In " + days + " days light will travel about " + distance + " miles.");
}
}
Upon execution console provides me with such the result:
"In 1000 days light will travel about 16070400000000 miles."
According by my logic, days and seconds vars should be int too, while their values are less than 2 147 483 647.
At this example days = 1000 and seconds = 86 400 000, so the values aren't that big.
But when I declare variables like this:
int lightspeed, days, seconds;
long distance;
I've strange result and for now I can accept it at no way.
"In 1000 days light will travel about -1367621632 miles."
Help me please.
When both seconds and lightspeed are declared as int, lightspeed * seconds is computed as the multiplication of ints, which causes an overflow (since 16070400000000 > 2147483647).
You can still leave them as int if you cast lightspeed or seconds to long, which will force the multiplication to be performed on longs :
distance = (long)lightspeed * seconds;
or
distance = lightspeed * (long)seconds;
Yes, only the distance is relevant, as Eran pointed out.
This behaviour is quite easy to remember if you just think of divison.
as above a / b performs integer division (truncation) given that a and b are integers whereas
(double) a / b
would return a double.
Note that the cast always refers to what follows after it. so in the case of an expression comprising of two integers only the first integer is casted to double.
`
I am looking for some java math.round formula which converts next to nearest 5000 value.
Suppose if the value is 15555, this should convert to 20000. If the value is 18555, this should also convert to 20000 (since this should give the next 5000 range).
So far I am trying this:
Math.round(value/ 5000.0) * 5000.0)
but if value is 15555, this gives me 15000. I want this to be 20000
You're then looking for Math.ceil(), not Math.round()
Math.ceil(value/ 5000.0) * 5000.0
Compare also nearest integer function with floor and ceiling functions
I'd probably prefer using basic integer operations for that (assuming value is a non-negative integer):
int remainder = value % 5000;
int result = remainder == 0 ? value : value - remainder + 5000;
Lets say i have long currentMillis and long oldMillis. The difference between the two timestamps is very tiny and always less than 1 second.
If i want to know the difference between the timestamps in milleseconds, i can do the following:
long difference = currentmillis-oldmillis;
And if i want to convert difference to seconds, i can just divide it by 1000. However if the difference in milliseconds is less than 1000 milliseconds(<1 second), dividing it by 1000 will result in 0.
How can i get the difference between the two timestamps if the difference is less than a second? For example, if the difference is 500 milliseconds, the desired output is 0.5 seconds.
Using float/double instead of long always returns 0.0 for some reason i don't understand.
My code:
private long oldmillis = 0, difference = 0;
private long calculateDifference()
{
long currentMillis = System.currentTimeMillis();
if (oldMillis == 0) oldMillis = currentMillis;
difference = currentMillis - oldMillis;
oldMillis = currentMillis;
return difference;
}
The method calculateDifference is called randomly with a small random time interval.
It sounds like you just need to convert the results into double before the division:
// This will work
double differenceMillis = currentMillis - oldMillis;
double differenceSeconds = differenceMillis / 1000;
// This will *not* work
double differenceSecondsBroken = (currentMillis - oldMillis) / 1000;
In the latter code, the division is performed using integer arithmetic, so you'll end up with a result of 0 that is then converted to a double.
An alternative which would work is to divide by 1000.0, which would force the arithmetic to be done using floating point:
double differenceSeconds = (currentMillis - oldMillis) / 1000.0;
This should be really trivial but all the methods I came up with are convoluted and waste operations (divide, take floor, scale up). Basically, I have random integers and I want to get the nearest 1000 multiple below it.
For example, if I have 6432, I really want 6000, or if I have 888 I want 0.
What the simplest expression that does this?
What you want is simply:
(number / 1000) * 1000;
How about doing something like this:
int OrigionalNum = 1503;
int NewNum = (OrigionalNum / 1000) * 1000;
It will give you an answer of 1 for 1503 / 1000, and then multiply it by 1000.
Right, sorry I can't think of the correct words to google this. So I'll have to ask.
I've got a long (System.currentTimeMillis())
Lets say
3453646345345345
I want to remove the last six (or other number of) digits and I think I can do this doing some kind of bit shift?
so I would end up with
3453646345
EDIT
I wanted to get the System.currentTimeMillis() within a time box, so if I ask for the time then ask again 29 seconds later it will return the same number but if I ask 31 seconds later it will return a different number. With the 30 second timebox being configurable.
You have to simply divide it by 1M long shorter = System.currentTimeMillis() / 1000000L;
To build on #Yob's answer, you can make the number of digits to remove configurable by creating a method like this:
public long removeDigits(long number, int digitsToRemove) {
return number / (long)Math.pow(10, digitsToRemove);
}
Depending on what you want to do (in base 10, I assume), you can do this:
int64_t radix = 1000000; // or some other power of 10
x -= x%radix; // last 6 decimal digits are now 0
// e.g: from 3453646345345345 to 3453646345000000
Or this (as in the previous answer):
x /= radix; // last 6 decimal digits are gone, the result rounded down
// e.g: from 3453646345345345 to 3453646345
Response to Edit
For your purposes, you could change radix in the modulus example to 30000:
int64_t timeInterval = 30000;
displayTime = actualTime - (actualTime % timeInterval);
Where displayTime and actualTime are in milliseonds. displayTime will, in this case, have a (rounded-down) granularity of 30 seconds while remaining a unit of milliseconds.
To have a rounded up granularity, you can do the following:
int64_t timeInterval = 30000;
int64_t modulus = actualTime % timeInterval;
displayTime = actualTime - modulus + (modulus?timeInterval:0);
Though, based on what you are asking, it seems you just want to update a display value only every few ticks. The following will work as well:
if((actualTime - displayTime) >= timeInterval){
displayTime = actualTime - (actualTime % timeInterval);
}
Pardon the C integer types, I just prefer to be unambiguous about the width of integer I'm using :P.