doubleに変換してからlong longに変換するオプションは、多くのユーザーに適していますが、52ビットの精度(double型の格納された仮数のサイズは52ビット)を提供し、その結果、精度が低下する可能性があるため、すべてではありません大きな数字で。 long doubleへの中間変換で問題を解決できるように見えますが、Microsoftコンパイラの制限がここで作用します-80ビット浮動小数点数をサポートせず、long double型をdouble型の類似物として受け入れます。
同時に、OCCIの基礎となるOCIはNumberからlong longへの変換を実行できます。 このため、次の機能があります。
sword OCINumberToInt (OCIError *err, const OCINumber *number, uword rsl_length, uword rsl_flag, void *rsl);
この関数は、パラメータに、初期数値const OCINumber * number 、結果の数値void * rslへのポインタ 、および結果の数値(バイト単位) uword rsl_lengthのポインタを取ります。 サポートされている結果サイズには8があります。 64ビット。 あとは、OCINumberを取得するだけです。
残念ながら、ここでは次の問題に直面しています-ResultSetからのOCCI(クエリの結果であるクラス)では、OCINumberを取得することもできません。また、OCINumberのラッパーであるoracle :: occi :: Numberクラスもそのアクセスを提供しません内臓をプライベートと宣言して:
private: /* Private constructor for constructing number from methods inside */ OCINumber getOCINumber() const; OCINumber data;
そしてここで、C ++で完全に異なる型を相互に変換する可能性を支援します。 Numberクラスには仮想メソッドがなく、 OCINumberデータメンバーがクラスの最初であるため、メモリ内のこのメンバーのアドレスはクラスインスタンスのアドレスと一致します。 つまり 書くだけで十分です。
oracle::occi::Number number; OCINumber *ociNumber = (OCINumber*)&number;
その結果、Numberを64ビット整数に変換する機能(MSVCの場合)は次のとおりです。
__int64 OCCINumberToInt64 (const oracle::occi::Number &number, OCIError *hError, bool bSigned) { const OCINumber *ociNumber = (const OCINumber*)&number; __int64 result; OCINumberToInt (hError, ociNumber, 8, bSigned ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED, &result); return result; }
また、必要なOCIエラーハンドル関数を取得するには、次のコードを使用できます。
oracle::occi::Environment env; ... OCIEnv *hEnv = env->getOCIEnvironment (); OCIError *hError = 0; OCIHandleAlloc (hEnv, (void**)&hError, OCI_HTYPE_ERROR, 0, 0); ... OCIHandleFree (hError, OCI_HTYPE_ERROR);