1#include "duckdb/main/capi/capi_internal.hpp"
2#include "duckdb/common/types/hugeint.hpp"
3#include "duckdb/common/types/decimal.hpp"
4#include "duckdb/common/operator/decimal_cast_operators.hpp"
5#include "duckdb/main/capi/cast/utils.hpp"
6#include "duckdb/main/capi/cast/to_decimal.hpp"
7
8using duckdb::Hugeint;
9using duckdb::hugeint_t;
10using duckdb::Value;
11
12double duckdb_hugeint_to_double(duckdb_hugeint val) {
13 hugeint_t internal;
14 internal.lower = val.lower;
15 internal.upper = val.upper;
16 return Hugeint::Cast<double>(input: internal);
17}
18
19static duckdb_decimal to_decimal_cast(double val, uint8_t width, uint8_t scale) {
20 if (width > duckdb::Decimal::MAX_WIDTH_INT64) {
21 return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<hugeint_t>>(source: val, width, scale);
22 }
23 if (width > duckdb::Decimal::MAX_WIDTH_INT32) {
24 return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int64_t>>(source: val, width, scale);
25 }
26 if (width > duckdb::Decimal::MAX_WIDTH_INT16) {
27 return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int32_t>>(source: val, width, scale);
28 }
29 return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int16_t>>(source: val, width, scale);
30}
31
32duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale) {
33 if (scale > width || width > duckdb::Decimal::MAX_WIDTH_INT128) {
34 return duckdb::FetchDefaultValue::Operation<duckdb_decimal>();
35 }
36 return to_decimal_cast(val, width, scale);
37}
38
39duckdb_hugeint duckdb_double_to_hugeint(double val) {
40 hugeint_t internal_result;
41 if (!Value::DoubleIsFinite(value: val) || !Hugeint::TryConvert<double>(value: val, result&: internal_result)) {
42 internal_result.lower = 0;
43 internal_result.upper = 0;
44 }
45
46 duckdb_hugeint result;
47 result.lower = internal_result.lower;
48 result.upper = internal_result.upper;
49 return result;
50}
51
52double duckdb_decimal_to_double(duckdb_decimal val) {
53 double result;
54 hugeint_t value;
55 value.lower = val.value.lower;
56 value.upper = val.value.upper;
57 duckdb::TryCastFromDecimal::Operation<hugeint_t, double>(input: value, result, error_message: nullptr, width: val.width, scale: val.scale);
58 return result;
59}
60