:- module float.
:- use_module builtin, exception, int, math, private_builtin.
:- pragma foreign_import_module("C", float).
:- pred (float:domain_checks).
:- mode (float:domain_checks) is semidet.
:- pragma inline((float:domain_checks)/0).
:- pragma inline((float:(/))/2).
float:(X_4 / Y_5) = Z_6 :-
		(if
			float:domain_checks,
			Y_5 = 0.00000000000000
		then
			V_7 = math:domain_error(V_8),
			V_8 = "float:\'/\'",
			exception:throw(V_7)
		else
			Z_6 = float:unchecked_quotient(X_4, Y_5)
		).
float:float(Int_3) = Float_4 :-
		int:to_float(Int_3, Float_4).
:- pragma foreign_proc("C", float:ceiling_to_int(X :: (builtin:in)) = (Ceil :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Ceil = (MR_Integer) ceil(X);
").
:- pragma foreign_proc("C", float:floor_to_int(X :: (builtin:in)) = (Floor :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Floor = (MR_Integer) floor(X);
").
:- pragma foreign_proc("C", float:round_to_int(X :: (builtin:in)) = (Round :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Round = (MR_Integer) floor(X + 0.5);
").
:- pragma foreign_proc("C", float:truncate_to_int(X :: (builtin:in)) = (Trunc :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	Trunc = (MR_Integer) X;
").
float:max(X_4, Y_5) = Max_6 :-
		(if
			float:(X_4 >= Y_5)
		then
			Max_6 = X_4
		else
			Max_6 = Y_5
		).
float:min(X_4, Y_5) = Min_6 :-
		(if
			float:(X_4 =< Y_5)
		then
			Min_6 = X_4
		else
			Min_6 = Y_5
		).
:- pragma foreign_proc("C", float:hash(F :: (builtin:in)) = (H :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
	H = MR_hash_float(F);
").
:- pragma foreign_proc("C", float:max = (Max :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "Max = ML_FLOAT_MAX;").
:- pragma foreign_proc("C", float:min = (Min :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "Min = ML_FLOAT_MIN;").
:- pragma foreign_proc("C", float:epsilon = (Eps :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "Eps = ML_FLOAT_EPSILON;").
:- pragma foreign_proc("C", float:radix = (Radix :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "Radix = ML_FLOAT_RADIX;").
:- pragma foreign_proc("C", float:mantissa_digits = (MantDig :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "MantDig = ML_FLOAT_MANT_DIG;").
:- pragma foreign_proc("C", float:min_exponent = (MinExp :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "MinExp = ML_FLOAT_MIN_EXP;").
:- pragma foreign_proc("C", float:max_exponent = (MaxExp :: (builtin:out)), [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "MaxExp = ML_FLOAT_MAX_EXP;").
:- pragma inline((float:domain_checks)/0).
:- pragma foreign_proc("C", float:domain_checks, [will_not_call_mercury, thread_safe, not_tabled_for_io, promise_pure], "
#ifdef ML_OMIT_MATH_DOMAIN_CHECKS
	SUCCESS_INDICATOR = MR_FALSE;
#else
	SUCCESS_INDICATOR = MR_TRUE;
#endif
").
:- pragma termination_info(float:'+'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(float:'-'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(float:'*'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(float:'/'((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(float:unchecked_quotient((builtin:in), (builtin:in)) = (builtin:uo), finite(0, [no, no, no]), cannot_loop).
:- pragma termination_info(float:'+'((builtin:in)) = (builtin:uo), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(float:'-'((builtin:in)) = (builtin:uo), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(float:'<'((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(float:'>'((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(float:'=<'((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(float:'>='((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).
:- pragma termination_info(float:float((builtin:in)) = (builtin:out), infinite, can_loop).
:- pragma termination_info(float:ceiling_to_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(float:floor_to_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(float:round_to_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(float:truncate_to_int((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(float:abs((builtin:in)) = (builtin:out), finite(0, [yes, no]), cannot_loop).
:- pragma termination_info(float:max((builtin:in), (builtin:in)) = (builtin:out), finite(0, [yes, yes, no]), cannot_loop).
:- pragma termination_info(float:min((builtin:in), (builtin:in)) = (builtin:out), finite(0, [yes, yes, no]), cannot_loop).
:- pragma termination_info(float:pow((builtin:in), (builtin:in)) = (builtin:out), finite(0, [no, no, no]), can_loop).
:- pragma termination_info(float:hash((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:max) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:min) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:epsilon) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:radix) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:mantissa_digits) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:min_exponent) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info((float:max_exponent) = (builtin:out), infinite, cannot_loop).
