Skip to content

Commit

Permalink
test cast between float and int
Browse files Browse the repository at this point in the history
  • Loading branch information
kuron99 committed Oct 17, 2023
1 parent cda1bd8 commit 580a326
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <jogasaki/utils/checkpoint_holder.h>

#include "common.h"
#include "constants.h"
#include "jogasaki/executor/process/impl/expression/evaluator_context.h"

namespace jogasaki::executor::process::impl::expression::details {
Expand Down Expand Up @@ -167,6 +168,7 @@ any to_int1(takatori::decimal::triple src, evaluator_context& ctx) {
decimal::context = decimal::IEEEContext(128);
decimal::Decimal value{src};
decimal::context.clear_status();
decimal::context.round(MPD_ROUND_DOWN);
auto rounded = value.to_integral();
if(! validate_decimal_in_int64(rounded)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
Expand All @@ -178,6 +180,7 @@ any to_int2(takatori::decimal::triple src, evaluator_context& ctx) {
decimal::context = decimal::IEEEContext(128);
decimal::Decimal value{src};
decimal::context.clear_status();
decimal::context.round(MPD_ROUND_DOWN);
auto rounded = value.to_integral();
if(! validate_decimal_in_int64(rounded)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
Expand All @@ -189,6 +192,7 @@ any to_int4(takatori::decimal::triple src, evaluator_context& ctx) {
decimal::context = decimal::IEEEContext(128);
decimal::Decimal value{src};
decimal::context.clear_status();
decimal::context.round(MPD_ROUND_DOWN);
auto rounded = value.to_integral();
if(! validate_decimal_in_int64(rounded)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
Expand All @@ -200,6 +204,7 @@ any to_int8(takatori::decimal::triple src, evaluator_context& ctx) {
decimal::context = decimal::IEEEContext(128);
decimal::Decimal value{src};
decimal::context.clear_status();
decimal::context.round(MPD_ROUND_DOWN);
auto rounded = value.to_integral();
if(! validate_decimal_in_int64(rounded)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
Expand Down Expand Up @@ -722,19 +727,43 @@ any to_character(float src, evaluator_context& ctx, std::optional<std::size_t> l
}

any to_int1(float src, evaluator_context& ctx) {
return validate_integer_range<std::int8_t, std::int32_t>(std::floor(src), ctx);
if(std::isinf(src) || std::isnan(src)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
}
return validate_integer_range<std::int8_t, std::int32_t>(std::trunc(src), ctx);
}

any to_int2(float src, evaluator_context& ctx) {
return validate_integer_range<std::int16_t, std::int32_t>(std::floor(src), ctx);
if(std::isinf(src) || std::isnan(src)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
}
return validate_integer_range<std::int16_t, std::int32_t>(std::trunc(src), ctx);
}


any to_int4(float src, evaluator_context& ctx) {
return validate_integer_range<std::int32_t>(std::floor(src), ctx);
if(std::isinf(src) || std::isnan(src)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
}
auto truncated = std::trunc(src);
// float values close to int4 max/min go over them when converted to int4
if(truncated > max_integral_float_convertible_to_int<kind::int4, kind::float4> ||
truncated < min_integral_float_convertible_to_int<kind::int4, kind::float4>) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
}
return validate_integer_range<std::int32_t>(truncated, ctx);
}

any to_int8(float src, evaluator_context& ctx) {
return validate_integer_range<std::int64_t>(std::floor(src), ctx);
if(std::isinf(src) || std::isnan(src)) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
}
auto truncated = std::trunc(src);
if(truncated > max_integral_float_convertible_to_int<kind::int8, kind::float4> ||
truncated < min_integral_float_convertible_to_int<kind::int8, kind::float4>) {
return any{std::in_place_type<error>, error(error_kind::overflow)};
}
return validate_integer_range<std::int64_t>(truncated, ctx);
}

any to_float8(float src, evaluator_context& ctx) {
Expand Down
135 changes: 135 additions & 0 deletions src/jogasaki/executor/process/impl/expression/details/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2018-2023 Project Tsurugi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include <cstddef>
#include <functional>

#include <takatori/scalar/expression.h>
#include <takatori/scalar/cast.h>
#include <takatori/scalar/match.h>
#include <takatori/scalar/binary.h>
#include <takatori/scalar/coalesce.h>
#include <takatori/scalar/compare.h>
#include <takatori/scalar/conditional.h>
#include <takatori/scalar/extension.h>
#include <takatori/scalar/function_call.h>
#include <takatori/scalar/immediate.h>
#include <takatori/scalar/let.h>
#include <takatori/scalar/unary.h>
#include <takatori/scalar/variable_reference.h>
#include <takatori/type/type_kind.h>
#include <yugawara/compiled_info.h>

#include <jogasaki/executor/process/impl/variable_table.h>
#include <jogasaki/data/any.h>
#include <jogasaki/memory/paged_memory_resource.h>
#include <jogasaki/memory/lifo_paged_memory_resource.h>
#include <jogasaki/executor/process/impl/expression/evaluator_context.h>

namespace jogasaki::executor::process::impl::expression::details {

using kind = meta::field_type_kind;

template <kind Kind>
using runtime_type = typename meta::field_type_traits<Kind>::runtime_type;

template <kind Int, kind Float>
constexpr runtime_type<Int> max_integral_float_convertible_to_int_source;

template <kind Int, kind Float>
constexpr runtime_type<Float> max_integral_float_convertible_to_int =
static_cast<runtime_type<Float>>(max_integral_float_convertible_to_int_source<Int, Float>);

// from float4
template <>
constexpr runtime_type<kind::int1> max_integral_float_convertible_to_int_source<kind::int1, kind::float4> =
static_cast<runtime_type<kind::int1>>(std::numeric_limits<std::int8_t>::max());

template <>
constexpr runtime_type<kind::int2> max_integral_float_convertible_to_int_source<kind::int2, kind::float4> =
static_cast<runtime_type<kind::int2>>(std::numeric_limits<std::int16_t>::max());

template <>
constexpr runtime_type<kind::int4> max_integral_float_convertible_to_int_source<kind::int4, kind::float4> =
static_cast<runtime_type<kind::int4>>(std::numeric_limits<std::int32_t>::max() - 64);

template <>
constexpr runtime_type<kind::int8> max_integral_float_convertible_to_int_source<kind::int8, kind::float4> =
static_cast<runtime_type<kind::int8>>(std::numeric_limits<std::int64_t>::max() - 256L*1024L*1024L*1024L);


// from float8
template <>
constexpr runtime_type<kind::int1> max_integral_float_convertible_to_int_source<kind::int1, kind::float8> =
static_cast<runtime_type<kind::int1>>(std::numeric_limits<std::int8_t>::max());

template <>
constexpr runtime_type<kind::int2> max_integral_float_convertible_to_int_source<kind::int2, kind::float8> =
static_cast<runtime_type<kind::int2>>(std::numeric_limits<std::int16_t>::max());

template <>
constexpr runtime_type<kind::int4> max_integral_float_convertible_to_int_source<kind::int4, kind::float8> =
static_cast<runtime_type<kind::int4>>(std::numeric_limits<std::int32_t>::max() - 2024);

template <>
constexpr runtime_type<kind::int8> max_integral_float_convertible_to_int_source<kind::int8, kind::float8> =
static_cast<runtime_type<kind::int8>>(std::numeric_limits<std::int64_t>::max() - 0); //TODO


template <kind Int, kind Float>
constexpr runtime_type<Int> min_integral_float_convertible_to_int_source;

template <kind Int, kind Float>
constexpr runtime_type<Float> min_integral_float_convertible_to_int =
static_cast<runtime_type<Float>>(min_integral_float_convertible_to_int_source<Int, Float>);

// from float4
template <>
constexpr runtime_type<kind::int1> min_integral_float_convertible_to_int_source<kind::int1, kind::float4> =
static_cast<runtime_type<kind::int1>>(std::numeric_limits<std::int8_t>::min());

template <>
constexpr runtime_type<kind::int2> min_integral_float_convertible_to_int_source<kind::int2, kind::float4> =
static_cast<runtime_type<kind::int2>>(std::numeric_limits<std::int16_t>::min());

template <>
constexpr runtime_type<kind::int4> min_integral_float_convertible_to_int_source<kind::int4, kind::float4> =
static_cast<runtime_type<kind::int4>>(std::numeric_limits<std::int32_t>::min());

template <>
constexpr runtime_type<kind::int8> min_integral_float_convertible_to_int_source<kind::int8, kind::float4> =
static_cast<runtime_type<kind::int8>>(std::numeric_limits<std::int64_t>::min() - 0); //TODO


// from float8
template <>
constexpr runtime_type<kind::int1> min_integral_float_convertible_to_int_source<kind::int1, kind::float8> =
static_cast<runtime_type<kind::int1>>(std::numeric_limits<std::int8_t>::min());

template <>
constexpr runtime_type<kind::int2> min_integral_float_convertible_to_int_source<kind::int2, kind::float8> =
static_cast<runtime_type<kind::int2>>(std::numeric_limits<std::int16_t>::min());

template <>
constexpr runtime_type<kind::int4> min_integral_float_convertible_to_int_source<kind::int4, kind::float8> =
static_cast<runtime_type<kind::int4>>(std::numeric_limits<std::int32_t>::min());

template <>
constexpr runtime_type<kind::int8> min_integral_float_convertible_to_int_source<kind::int8, kind::float8> =
static_cast<runtime_type<kind::int8>>(std::numeric_limits<std::int64_t>::min() - 0); //TODO

} // namespace
Loading

0 comments on commit 580a326

Please sign in to comment.