-5

I have been doing an operation in C++ on the timer struct of Linux provided by the interface "clock_gettime(CLOCK_MONOTONIC, &CurrentTime)"

#include <iostream>
#include <time.h>

int main()
{
    struct timespec CurrentTime;
    CurrentTime.tv_sec = 28220;
    CurrentTime.tv_nsec = 461189000;

    unsigned long long TimeNow;
    TimeNow = (28220 * 1000000) + (461189000 * 0.001);

    std::cout << TimeNow;
}

yet the result always giving TimeNow as a Zero.

I would appreciate if any has answer to this question or a lead to follow. It was done using GCC Compiler

Code Snipped could be found here http://rextester.com/XRR83683

AYZAB
  • 5
  • 3
  • 2
    Instead of sprinkling bits of C++ code throughout the question, how about providing a single [mcve]? – Sam Varshavchik Oct 09 '16 at 23:22
  • [Works for me](http://rextester.com/XSP25641) – Igor Tandetnik Oct 09 '16 at 23:28
  • Thank you Igor, Try replacing the value instead of the variables, it would result to 0 http://rextester.com/XRR83683 – AYZAB Oct 09 '16 at 23:31
  • Please edit your post. Put the code there and format it properly. Neither the speach-code mix in your post nor the poorly formatted code in your comment are readable. – YakovL Oct 09 '16 at 23:33
  • Kindly Find the code here http://rextester.com/XRR83683 – AYZAB Oct 09 '16 at 23:34
  • 3
    What part of "edit your post and put the code there" you don't understand? – Sam Varshavchik Oct 09 '16 at 23:35
  • `(28220 * 1000000)` is an `int` multiplied by an `int`, and likely overflows. – Dmitri Oct 09 '16 at 23:38
  • 1
    @AhmedYzab I'm downvoting due to no research. What's so difficult in printing out the intermediate results, thus focusing on what the problem is? [Here is your code with those simple tests I put in](http://rextester.com/LPSOBR20168). Then the initial question from you should have been a simple "why when I multiply these two numbers, I get the wrong answer?". – PaulMcKenzie Oct 09 '16 at 23:39
  • @PaulMcKenzie: Thank you for your comments, if you may excuse me but I still do not understand how the calculation yields to 0. I have done these checks and cannot understand why starting from having the value 27918 for the CurrentTime.tv_sec, the calculation yields to 0. – AYZAB Oct 09 '16 at 23:46
  • 1
    in `(28220 * 1000000) + (461189000 * 0.001)`, `(28220 * 1000000)` is calculated with `int` types, and overflows... and `(461189000 * 0.001)` is calculated with `double`s and added to it, yielding a `double`. Then that wildly incorrect `double` value is converted to `unsigned long long` for assignment to `TimeNow`. Try using `28220LL` instead of `28220` and you'll get a reasonable answer. – Dmitri Oct 09 '16 at 23:53
  • I have edited the question showing that the problem is the overflow just as @Dmitri suggested (he should turn his comments into an answer...). I think the edit shows what is actually being asked but if the edit isn't helpful please roll it back. – Jerry Jeremiah Oct 10 '16 at 00:00
  • Thank you for the answer again, My objective is not to correct it, but actually to understand what is happenning exactly and being able to do it with handwriting calculations: I have done what you have described on hand and doesnt yield to 0 (28220 * 1000000) = (2450196224) "after the truncation for int", The Double calculation produces (461189). adding them together in double yields to "2450657413" which is in hex 92121085. So i don't understand, is the double value casted to the unsigned long long, is it an implicit truncation of the IEEE double to the 64bits? – AYZAB Oct 10 '16 at 00:10

1 Answers1

0

In the line:

TimeNow = (28220 * 1000000) + (461189000 * 0.001);

the (28220 * 1000000) part is calculated using ints, and (with 32-bit int) overflows giving an incorrect value (likely -1844771072).

The (461189000 * 0.001) part is calculated using doubles, because of the 0.001 double constant, giving 461189.0 as a double.

The two are then added together, giving a negative double value... when that negative double is converted to unsigned long long for the assignment to TimeNow, it's being converted as 0, probably because that's the closest value in its range to any negative number. This is different from converting a negative integer type to unsigned, which would "wrap around".

Dmitri
  • 9,175
  • 2
  • 27
  • 34
  • Thanks for the answer, it really makes sense to me now (At the end the question is not trivial, lots of people who do not have clear answer down-voted it :) ) But your answer takes me to the second part of the question, Why it works fine with variables as shown [link](http://rextester.com/EIUEQ62755)here – AYZAB Oct 10 '16 at 00:34
  • @AhmedYzab that's because on that implementation, `time_t` (which is the type of `CurrentTime.tv_sec`) is wider than 32-bit so the multiplication is also performed in the wider type and doesn't overflow. – Dmitri Oct 10 '16 at 00:36