# [boost.date_time] Plattform-spezifische Caveats?

• Hallo zusammen

Folgender Code:

``````#include <boost/assign/list_of.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <iostream>
#include <vector>

using namespace boost::assign;
using namespace boost::posix_time;
using namespace std;

int main() {
time_duration timeStep(minutes(15));
vector<time_duration> differences(100, minutes(15));
for (unsigned int i = 0; i < differences.size(); ++i) {
time_duration::tick_type numerator(timeStep.total_milliseconds());
time_duration::tick_type denominator(differences.at(i).total_milliseconds());
double multiplicator = numerator / denominator;
double random = rand();
cout << "num: " << numerator << ", " << "den: " << denominator << endl;
cout << i << ": " << (random * multiplicator) << " (mult: " << multiplicator << ')' << endl;
}
return 0;
}
``````

Gibt auf meinem Entwicklungs-Rechner folgenden Output:

``````num: 900000, den: 900000
0: 41 (mult: 1)
num: 900000, den: 900000
1: 18467 (mult: 1)
...
num: 900000, den: 900000
99: 16541 (mult: 1)
``````

Auf meiner Embedded-Zielplattform hingegen erhalte ich folgenden, ungekürzten Output:

``````num: 900000, den: 900000
0: 6.2635e+09 (mult: 3.47145)
num: 900000, den: 900000
1: 6.43756e-301 (mult: 7.61038e-310)
num: 900000, den: 4614999431078329248
2: -5936.41 (mult: -3.53002e-06)
num: 900000, den: 153640644625800
3: -6053.29 (mult: -3.53036e-06)
num: 900000, den: -4697926556549346372
4: 2.49012e+10 (mult: 12.7193)
num: 900000, den: -4697925780254122828
1074507244: 3.18828e-301 (mult: 7.51531e-310)
``````

Traurig dabei ist: Wenn ich den "total_milliseconds()"-Teil durch Konstanten ersetze...

``````time_duration::tick_type numerator(900000);
time_duration::tick_type denominator(900000);
``````

funktioniert der Code wie erwartet:

``````num: 900000, den: 900000
0: 1.80429e+09 (mult: 1)
num: 900000, den: 900000
1: 8.46931e+08 (mult: 1)
...
num: 900000, den: 900000
99: 1.9563e+09 (mult: 1)
``````

Gibt es irgendwelche Caveats, dich ich im Zusammenhang mit dieser Funktion beachten sollte?

Danke für jeden Hinweis und Gruss
Kessi

• Nach zusätzlichen Experimenten zeichnet sich ab, dass "time_duration::tick_type" auf dem Zielsystem eine 8-Byte grosse Zahl ist. Sie von Anfang an als "double" zu verwenden, löst das Problem nicht, von "total_milliseconds" auf "total_seconds" zu wechseln aber schon:

``````double numerator(timeStep.total_seconds());
double denominator(differences.at(i).total_seconds());
``````

Das ist für meinen Use Case ausreichend, lässt mich aber mit einem sehr unangenehmen Gefühl zurück. Übrigens, folgender Code funktioniert ebenfalls:

``````long numerator(timeStep.total_milliseconds());
long denominator(differences.at(i).total_milliseconds());
``````

Dabei ist zu beachten, dass "long" auf dem Zielsystem ein 4-Byte Datentyp ist. Die Verwendung von "total_milliseconds" alleine macht den Absturz also noch nicht perfekt, erst, das Resultat in einem "long long" (= "time_duration::tick_type") zu Speichern, bringt das System zum Versagen... Das aber auch nicht im Allgemeinen Fall - anstatt eines Vektors von "time_duration"s nur eine einzelne zu verwenden, löst das Problem ebenfalls.

``````time_duration timeStep(minutes(15));
time_duration difference(minutes(15));
``````

Ich werde mich vorerst auf "total_seconds()" beschränken, muss aber davon ausgehen, dass mir dieses System noch sehr viel Ärger bescherern wird. Vielleicht ist ein Post in der Boost Mailing-Liste ebenfalls angebracht. Werde das bei Gelegenheit nachholen.

Danke auf jeden Fall an alle Gegenleser und Gruss
Kessi

• Um Boost noch komplett aus der Gleichung zu nehmen:

``````#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;

int main() {
long long step(900000);
vector<long long> differences(100, 900000);
for (unsigned int i = 0; i < differences.size(); ++i) {
double numerator(step);
double denominator(differences.at(i));
double multiplicator = numerator / denominator;
double random = rand();
cout << i << ": " << (random * multiplicator) << " (mult: " << multiplicator << ", " << "num: " << numerator << ", " << "den: " << denominator << ')' << endl;
}
return 0;
}
``````

Resultat:

``````0: inf (mult: inf, num: 900000, den: 3.47145)
1: 5.99277e+13 (mult: 70758.6, num: 900000, den: 7.5603e-310)
2: 2.14001e-160 (mult: 1.27253e-169, num: 900000, den: -1.26001e-05)
35420: 2.22566e+14 (mult: 129803, num: 900000, den: -1.26015e-05)
``````

Vektoren von "long long"s sind auf dieser Plattform scheinbar eine böse Sache, denn:

``````vector<long long> differences(1, 900000);
``````

ergibt:

``````0: inf (mult: inf, num: 900000, den: 3.47145)
``````

aber:

``````long long difference(900000);
for (unsigned int i = 0; i < 100; ++i) {
double numerator(step);
double denominator(difference);
...
``````

resultiert in:

``````0: 41 (mult: 1, num: 900000, den: 900000)
1: 18467 (mult: 1, num: 900000, den: 900000)
...
99: 16541 (mult: 1, num: 900000, den: 900000)
``````

Ich schätze, jetzt ist es definitiv ein Fall für den Plattform-Hersteller...

Danke trotzdem für eure Geduld und Gruss
Kessi

• Klarer Kompilerfeler :p