85 public::
operator(==),
operator(>),
operator(<),
operator(>=),
operator(<=)
86 public::
operator(+),
operator(-),
operator(*),
operator(/),
mod,
modulo
93 integer,
parameter:: imin = -2
94 integer,
parameter:: imax = 8
95 real(DP),
parameter:: scale_factor = 1.0e+3_dp
96 real(DP),
parameter:: scale_factor_xx (-(imax+1):imax+1) = &
98 & 1.0e-24_DP, 1.0e-21_DP, 1.0e-18_DP, 1.0e-15_DP, &
99 & 1.0e-12_DP, 1.0e-9_DP, 1.0e-6_DP, 1.0e-3_DP, &
101 & 1.0e+3_DP, 1.0e+6_DP, 1.0e+9_DP, 1.0e+12_DP, &
102 & 1.0e+15_DP, 1.0e+18_DP, 1.0e+21_DP, 1.0e+24_DP, &
105 integer,
parameter:: scale_factor_int = 1000
106 integer,
parameter:: scale_factor_int_xx (0:3) = &
107 & (/ 1, 1000, 1000000, 1000000000 /)
130 integer:: sec_ary(imin:imax) = 0
131 logical:: flag_negative = .false.
132 logical:: dummy = .false.
135 interface assignment(=)
136 module procedure dcscaledseccreater
137 module procedure dcscaledseccreated
138 module procedure dcscaledseccreatei
140 module procedure dcscaledsectonumr
141 module procedure dcscaledsectonumd
142 module procedure dcscaledsectonumi
149 interface operator(==)
150 module procedure dcscaledsec_eq_ss
151 module procedure dcscaledsec_eq_si
152 module procedure dcscaledsec_eq_is
153 module procedure dcscaledsec_eq_sr
154 module procedure dcscaledsec_eq_rs
155 module procedure dcscaledsec_eq_sd
156 module procedure dcscaledsec_eq_ds
159 interface operator(>)
160 module procedure dcscaledsec_gt_ss
161 module procedure dcscaledsec_gt_si
162 module procedure dcscaledsec_gt_is
165 interface operator(<)
166 module procedure dcscaledsec_lt_ss
167 module procedure dcscaledsec_lt_si
168 module procedure dcscaledsec_lt_is
171 interface operator(>=)
172 module procedure dcscaledsec_ge_ss
173 module procedure dcscaledsec_ge_si
174 module procedure dcscaledsec_ge_is
177 interface operator(<=)
178 module procedure dcscaledsec_le_ss
179 module procedure dcscaledsec_le_si
180 module procedure dcscaledsec_le_is
183 interface operator(+)
184 module procedure dcscaledsec_add_ss
185 module procedure dcscaledsec_add_si
186 module procedure dcscaledsec_add_is
187 module procedure dcscaledsec_add_sr
188 module procedure dcscaledsec_add_rs
189 module procedure dcscaledsec_add_sd
190 module procedure dcscaledsec_add_ds
193 interface operator(-)
194 module procedure dcscaledsec_sub_s
195 module procedure dcscaledsec_sub_ss
196 module procedure dcscaledsec_sub_si
197 module procedure dcscaledsec_sub_is
198 module procedure dcscaledsec_sub_sr
199 module procedure dcscaledsec_sub_rs
200 module procedure dcscaledsec_sub_sd
201 module procedure dcscaledsec_sub_ds
204 interface operator(*)
205 module procedure dcscaledsec_mul_ss
206 module procedure dcscaledsec_mul_si
207 module procedure dcscaledsec_mul_is
208 module procedure dcscaledsec_mul_sd
209 module procedure dcscaledsec_mul_ds
210 module procedure dcscaledsec_mul_sr
211 module procedure dcscaledsec_mul_rs
214 interface operator(/)
215 module procedure dcscaledsec_div_si
216 module procedure dcscaledsec_div_sr
217 module procedure dcscaledsec_div_sd
218 module procedure dcscaledsec_div_ss
222 module procedure dcscaledsec_mod_si
223 module procedure dcscaledsec_mod_sr
224 module procedure dcscaledsec_mod_sd
225 module procedure dcscaledsec_mod_ss
229 module procedure dcscaledsec_modulo_si
230 module procedure dcscaledsec_modulo_sr
231 module procedure dcscaledsec_modulo_sd
232 module procedure dcscaledsec_modulo_ss
236 module procedure dcscaledsec_abs_s
240 module procedure dcscaledsec_int_s
244 module procedure dcscaledsec_sign_si
245 module procedure dcscaledsec_sign_sr
246 module procedure dcscaledsec_sign_sd
247 module procedure dcscaledsec_sign_ss
251 module procedure dcscaledsec_floor_s
255 module procedure dcscaledsec_ceiling_s
262 subroutine dcscaledseccreatei(sclsec, sec)
265 integer,
intent(in):: sec
267 call dcscaledseccreated(sclsec, real( sec, dp ))
268 end subroutine dcscaledseccreatei
272 subroutine dcscaledseccreater(sclsec, sec)
275 real,
intent(in):: sec
277 call dcscaledseccreated(sclsec, real( sec, dp ))
278 end subroutine dcscaledseccreater
282 subroutine dcscaledseccreated(sclsec, sec)
289 real(DP),
intent(in):: sec
291 real(DP):: work_sec, print_sec
292 integer:: i, cd, move_up, work_sec_scl_nint
295 character(STRING) :: cause_c
296 character(*),
parameter:: subname =
'dc_scaledsec'
303 if ( sec < 0.0_dp )
then
304 sclsec % flag_negative = .true.
307 sclsec % flag_negative = .false.
311 if ( work_sec > scale_factor_xx(imax + 1) )
then
313 &
'input number (%f) is too large.', &
320 do i = imax, imin, -1
322 work_sec_scl_nint = nint( work_sec * scale_factor_xx(-i) )
323 if ( .not. work_sec < scale_factor_xx(i) &
324 & .or. ( i == imin .and. work_sec_scl_nint >= 1 ) )
then
327 sclsec % sec_ary(i) = work_sec_scl_nint
329 sclsec % sec_ary(i) =
int( work_sec / scale_factor_xx(i) )
331 work_sec = work_sec - sclsec % sec_ary(i) * scale_factor_xx(i)
332 cd = cd + count_digit( sclsec % sec_ary(i) )
335 if ( .not.
abs( work_sec ) < scale_factor_xx(i-1) )
then
347 sclsec % sec_ary(i) = sclsec % sec_ary(i) + move_up
349 do while ( sclsec % sec_ary(i) >= scale_factor_int )
350 move_up = move_up + 1
351 sclsec % sec_ary(i) = sclsec % sec_ary(i) - scale_factor_int
356 call storeerror(stat, subname, cause_c=cause_c)
358 end subroutine dcscaledseccreated
362 subroutine dcscaledsectonumi(sec, sclsec)
365 integer,
intent(out):: sec
369 call dcscaledsectonumd(secd, sclsec)
371 end subroutine dcscaledsectonumi
375 subroutine dcscaledsectonumr(sec, sclsec)
378 real,
intent(out):: sec
382 call dcscaledsectonumd(secd, sclsec)
384 end subroutine dcscaledsectonumr
388 subroutine dcscaledsectonumd(sec, sclsec)
391 real(DP),
intent(out):: sec
397 do i = imax, imin, -1
398 sec = sec + ( sclsec % sec_ary(i) * scale_factor_xx(i) )
400 if ( sclsec % flag_negative ) sec = - sec
401 end subroutine dcscaledsectonumd
434 integer,
intent(in),
optional :: unit
435 character(*),
intent(in),
optional:: indent
437 integer :: out_unit, sec_ary_rev(imin:imax)
439 character(STRING):: indent_str
444 if (
present(unit))
then
452 if (
present(indent) )
then
453 if ( len(indent) /= 0 )
then
454 indent_len = len(indent)
455 indent_str(1:indent_len) = indent
459 sec_ary_rev(imin:imax) = sclsec % sec_ary(imax:imin:-1)
460 if ( sclsec % flag_negative )
then
465 if ( imax - imin + 1 == 6 )
then
467 & indent_str(1:indent_len) // &
468 &
'#<DC_SCALED_SEC:: @sign=%c @yotta=%d @exa=%d @tera=%d @mega=%d @base=%d @micro=%d>', &
469 & i = sec_ary_rev, c1 =
sign )
470 elseif ( imax - imin + 1 == 11 )
then
472 & indent_str(1:indent_len) // &
473 &
'#<DC_SCALED_SEC:: @sign=%c @yotta=%d @zetta=%d @exa=%d @peta=%d @tera=%d', &
474 & i = sec_ary_rev(imin:imin+4), c1 =
sign )
476 & indent_str(1:indent_len) // &
477 &
' @giga=%d @mega=%d @kilo=%d @base=%d @milli=%d @micro=%d>', &
478 & i = sec_ary_rev(imax-5:imax) )
481 & indent_str(1:indent_len) // &
482 &
'#<DC_SCALED_SEC:: @sign=%c @sec_ary=%*d>', &
483 & i = sec_ary_rev, n = (/ imax - imin + 1 /), c1 =
sign )
503 logical function dcscaledsec_eq_ss(sclsec1, sclsec2)
result(result)
509 if ( sclsec1 % flag_negative .and. .not. sclsec2 % flag_negative )
then
513 elseif ( .not. sclsec1 % flag_negative .and. sclsec2 % flag_negative )
then
518 do i = imax, imin, -1
519 if ( .not. sclsec1 % sec_ary(i) == sclsec2 % sec_ary(i) )
then
526 end function dcscaledsec_eq_ss
530 logical function dcscaledsec_eq_si(sclsec, sec)
result(result)
533 integer,
intent(in):: sec
537 if ( sclsec % flag_negative .and. .not. sec < 0 )
then
540 elseif ( .not. sclsec % flag_negative .and. sec < 0 )
then
545 if (
abs(sec) > scale_factor_int_xx(3) )
then
547 result = sclsec == sclsec2
549 if ( .not. all( sclsec % sec_ary(imin:-1) == (/0, 0/) ) &
550 & .or. .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) )
then
554 sec1 = sclsec % sec_ary(0)
556 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
560 end function dcscaledsec_eq_si
564 logical function dcscaledsec_eq_is(sec, sclsec)
result(result)
566 integer,
intent(in):: sec
569 result = sclsec == sec
570 end function dcscaledsec_eq_is
574 logical function dcscaledsec_eq_sr(sclsec, sec)
result(result)
577 real,
intent(in):: sec
581 result = sclsec == sclsec2
582 end function dcscaledsec_eq_sr
586 logical function dcscaledsec_eq_rs(sec, sclsec)
result(result)
588 real,
intent(in):: sec
593 result = sclsec == sclsec2
594 end function dcscaledsec_eq_rs
598 logical function dcscaledsec_eq_sd(sclsec, sec)
result(result)
601 real(dp),
intent(in):: sec
605 result = sclsec == sclsec2
606 end function dcscaledsec_eq_sd
610 logical function dcscaledsec_eq_ds(sec, sclsec)
result(result)
612 real(dp),
intent(in):: sec
617 result = sclsec == sclsec2
618 end function dcscaledsec_eq_ds
635 logical function dcscaledsec_gt_ss(sclsec1, sclsec2)
result(result)
640 logical:: both_negative, flag_equal
645 if ( sclsec1 % flag_negative .and. .not. sclsec2 % flag_negative )
then
648 elseif ( .not. sclsec1 % flag_negative .and. sclsec2 % flag_negative )
then
651 elseif ( sclsec1 % flag_negative .and. sclsec2 % flag_negative )
then
652 both_negative = .true.
654 both_negative = .false.
657 do i = imax, imin, -1
658 if ( sclsec1 % sec_ary(i) > sclsec2 % sec_ary(i) )
then
662 elseif ( sclsec1 % sec_ary(i) < sclsec2 % sec_ary(i) )
then
669 if ( .not. flag_equal .and. both_negative ) result = .not. result
671 end function dcscaledsec_gt_ss
688 logical function dcscaledsec_gt_si(sclsec, factor)
result(result)
691 integer,
intent(in):: factor
693 integer:: i, sec1, factor_abs
694 logical:: both_negative
696 if ( sclsec % flag_negative .and. .not. factor < 0 )
then
699 elseif ( .not. sclsec % flag_negative .and. factor < 0 )
then
702 elseif ( sclsec % flag_negative .and. factor < 0 )
then
703 both_negative = .true.
705 both_negative = .false.
708 factor_abs =
abs(factor)
710 if ( factor_abs > scale_factor_int_xx(3) )
then
712 result = sclsec > factor_scl
715 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) )
then
718 sec1 = sclsec % sec_ary(0)
720 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
722 if ( sec1 == factor_abs )
then
723 result = .not. all( sclsec % sec_ary(imin:-1) == (/0, 0/) )
725 result = sec1 > factor_abs
729 if ( both_negative ) result = .not. result
732 end function dcscaledsec_gt_si
749 logical function dcscaledsec_gt_is(factor, sclsec)
result(result)
751 integer,
intent(in):: factor
754 integer:: i, sec1, factor_abs
755 logical:: both_negative
757 if ( sclsec % flag_negative .and. .not. factor < 0 )
then
760 elseif ( .not. sclsec % flag_negative .and. factor < 0 )
then
763 elseif ( sclsec % flag_negative .and. factor < 0 )
then
764 both_negative = .true.
766 both_negative = .false.
769 factor_abs =
abs(factor)
771 if ( factor_abs > scale_factor_int_xx(3) )
then
773 result = factor_scl > sclsec
776 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) )
then
779 sec1 = sclsec % sec_ary(0)
781 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
783 if ( sec1 == factor_abs )
then
786 result = factor_abs > sec1
790 if ( both_negative ) result = .not. result
792 end function dcscaledsec_gt_is
809 logical function dcscaledsec_lt_ss(sclsec1, sclsec2)
result(result)
813 logical:: both_negative, flag_equal
818 if ( sclsec1 % flag_negative .and. .not. sclsec2 % flag_negative )
then
821 elseif ( .not. sclsec1 % flag_negative .and. sclsec2 % flag_negative )
then
824 elseif ( sclsec1 % flag_negative .and. sclsec2 % flag_negative )
then
825 both_negative = .true.
827 both_negative = .false.
830 do i = imax, imin, -1
831 if ( sclsec1 % sec_ary(i) > sclsec2 % sec_ary(i) )
then
835 elseif ( sclsec1 % sec_ary(i) < sclsec2 % sec_ary(i) )
then
842 if ( .not. flag_equal .and. both_negative ) result = .not. result
844 end function dcscaledsec_lt_ss
861 logical function dcscaledsec_lt_si(sclsec, factor)
result(result)
864 integer,
intent(in):: factor
866 integer:: i, sec1, factor_abs
867 logical:: both_negative
869 if ( sclsec % flag_negative .and. .not. factor < 0 )
then
872 elseif ( .not. sclsec % flag_negative .and. factor < 0 )
then
875 elseif ( sclsec % flag_negative .and. factor < 0 )
then
876 both_negative = .true.
878 both_negative = .false.
881 factor_abs =
abs(factor)
883 if ( factor_abs > scale_factor_int_xx(3) )
then
885 result = sclsec < factor_scl
888 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) )
then
891 sec1 = sclsec % sec_ary(0)
893 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
895 if ( sec1 == factor_abs )
then
898 result = sec1 < factor_abs
902 if ( both_negative ) result = .not. result
904 end function dcscaledsec_lt_si
921 logical function dcscaledsec_lt_is(factor, sclsec)
result(result)
923 integer,
intent(in):: factor
926 integer:: i, sec1, factor_abs
927 logical:: both_negative
929 if ( sclsec % flag_negative .and. .not. factor < 0 )
then
932 elseif ( .not. sclsec % flag_negative .and. factor < 0 )
then
935 elseif ( sclsec % flag_negative .and. factor < 0 )
then
936 both_negative = .true.
938 both_negative = .false.
941 factor_abs =
abs(factor)
943 if ( factor_abs > scale_factor_int_xx(3) )
then
945 result = factor_scl < sclsec
948 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) )
then
951 sec1 = sclsec % sec_ary(0)
953 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
955 if ( sec1 == factor_abs )
then
956 result = .not. all( sclsec % sec_ary(imin:-1) == (/0, 0/) )
958 result = factor_abs < sec1
962 if ( both_negative ) result = .not. result
965 end function dcscaledsec_lt_is
982 logical function dcscaledsec_ge_ss(sclsec1, sclsec2)
result(result)
986 result = .not. sclsec1 < sclsec2
987 end function dcscaledsec_ge_ss
1004 logical function dcscaledsec_ge_si(sclsec, factor)
result(result)
1007 integer,
intent(in):: factor
1009 result = .not. sclsec < factor
1010 end function dcscaledsec_ge_si
1027 logical function dcscaledsec_ge_is(factor, sclsec)
result(result)
1029 integer,
intent(in):: factor
1032 result = .not. factor < sclsec
1033 end function dcscaledsec_ge_is
1050 logical function dcscaledsec_le_ss(sclsec1, sclsec2)
result(result)
1054 result = .not. sclsec1 > sclsec2
1055 end function dcscaledsec_le_ss
1072 logical function dcscaledsec_le_si(sclsec, factor)
result(result)
1075 integer,
intent(in):: factor
1077 result = .not. sclsec > factor
1078 end function dcscaledsec_le_si
1095 logical function dcscaledsec_le_is(factor, sclsec)
result(result)
1097 integer,
intent(in):: factor
1100 result = .not. factor > sclsec
1101 end function dcscaledsec_le_is
1118 type(
dc_scaled_sec) function dcscaledsec_add_ss(sclsec1, sclsec2) result(result)
1123 integer:: i, move_up
1124 logical:: both_negative, sclsec2_flag_negative
1128 both_negative = .false.
1133 sclsec2_flag_negative = sclsec2 % flag_negative
1134 if ( sclsec1 % flag_negative )
then
1135 both_negative = .true.
1136 sclsec2_flag_negative = .not. sclsec2_flag_negative
1138 if ( sclsec2_flag_negative )
then
1139 sclsec1_opsign = sclsec1
1140 sclsec1_opsign % flag_negative = .false.
1141 sclsec2_opsign = sclsec2
1142 sclsec2_opsign % flag_negative = .false.
1143 result = sclsec1_opsign - sclsec2_opsign
1144 if ( both_negative )
then
1145 result % flag_negative = .not. result % flag_negative
1154 result % sec_ary(i) = sclsec1 % sec_ary(i) + sclsec2 % sec_ary(i) + move_up
1155 if ( .not. result % sec_ary(i) < scale_factor_int )
then
1156 if ( i == imax )
then
1158 &
'DC_SCALED_SEC must be smaller than 10^24' )
1160 move_up = result % sec_ary(i) / scale_factor_int
1161 result % sec_ary(i) =
mod( result % sec_ary(i), scale_factor_int )
1167 if ( both_negative )
then
1168 result % flag_negative = .true.
1170 result % flag_negative = .false.
1173 end function dcscaledsec_add_ss
1193 integer,
intent(in):: factor
1197 result = sclsec + factor_scl
1198 end function dcscaledsec_add_si
1217 integer,
intent(in):: factor
1222 result = factor_scl + sclsec
1223 end function dcscaledsec_add_is
1243 real,
intent(in):: factor
1247 result = sclsec + factor_scl
1248 end function dcscaledsec_add_sr
1267 real,
intent(in):: factor
1272 result = sclsec + factor_scl
1273 end function dcscaledsec_add_rs
1293 real(dp),
intent(in):: factor
1297 result = sclsec + factor_scl
1298 end function dcscaledsec_add_sd
1317 real(dp),
intent(in):: factor
1322 result = sclsec + factor_scl
1323 end function dcscaledsec_add_ds
1342 result % flag_negative = .not. sclsec % flag_negative
1343 result % sec_ary = sclsec % sec_ary
1344 end function dcscaledsec_sub_s
1361 type(
dc_scaled_sec) function dcscaledsec_sub_ss(sclsec1, sclsec2) result(result)
1365 integer:: i, move_down
1366 logical:: both_negative, sclsec2_flag_negative
1371 both_negative = .false.
1376 sclsec2_flag_negative = sclsec2 % flag_negative
1377 if ( sclsec1 % flag_negative )
then
1378 both_negative = .true.
1379 sclsec2_flag_negative = .not. sclsec2_flag_negative
1381 if ( sclsec2_flag_negative )
then
1382 sclsec1_opsign = sclsec1
1383 sclsec1_opsign % flag_negative = .false.
1384 sclsec2_opsign = sclsec2
1385 sclsec2_opsign % flag_negative = .false.
1387 result = sclsec1_opsign + sclsec2_opsign
1388 if ( both_negative )
then
1389 result % flag_negative = .not. result % flag_negative
1397 sclsec1_nosign = sclsec1
1398 sclsec1_nosign % flag_negative = .false.
1399 sclsec2_nosign = sclsec2
1400 sclsec2_nosign % flag_negative = .false.
1402 if ( sclsec1_nosign > sclsec2_nosign )
then
1403 result % flag_negative = .false.
1404 large = sclsec1_nosign
1405 small = sclsec2_nosign
1406 elseif ( sclsec1_nosign < sclsec2_nosign )
then
1407 result % flag_negative = .true.
1408 large = sclsec2_nosign
1409 small = sclsec1_nosign
1417 result % sec_ary(i) = large % sec_ary(i) - small % sec_ary(i) + move_down
1418 if ( result % sec_ary(i) < 0 )
then
1419 move_down = ( result % sec_ary(i) / scale_factor_int ) - 1
1420 result % sec_ary(i) = &
1421 &
mod( result % sec_ary(i), scale_factor_int ) + scale_factor_int
1427 if ( both_negative )
then
1428 result % flag_negative = .not. result % flag_negative
1431 end function dcscaledsec_sub_ss
1451 integer,
intent(in):: factor
1455 result = sclsec - factor_scl
1456 end function dcscaledsec_sub_si
1475 integer,
intent(in):: factor
1480 result = factor_scl - sclsec
1481 end function dcscaledsec_sub_is
1501 real,
intent(in):: factor
1505 result = sclsec - factor_scl
1506 end function dcscaledsec_sub_sr
1525 real,
intent(in):: factor
1530 result = factor_scl - sclsec
1531 end function dcscaledsec_sub_rs
1551 real(dp),
intent(in):: factor
1555 result = sclsec - factor_scl
1556 end function dcscaledsec_sub_sd
1575 real(dp),
intent(in):: factor
1580 result = factor_scl - sclsec
1581 end function dcscaledsec_sub_ds
1598 type(
dc_scaled_sec) function dcscaledsec_mul_ss(sclsec1, sclsec2) result(result)
1602 integer:: sec_ary_int(imin:imax,imin:imax)
1604 integer:: i, j, move_up
1607 if ( sclsec1 == zero_sec .or. sclsec2 == zero_sec )
then
1612 if ( sclsec1 % flag_negative )
then
1613 result % flag_negative = .not. sclsec2 % flag_negative
1615 result % flag_negative = sclsec2 % flag_negative
1619 sec_ary_int(:,:) = 0
1622 sec_ary_int(i,j) = &
1623 & sclsec1 % sec_ary(j) * sclsec2 % sec_ary(i) + move_up
1624 if ( i + j > imax .and. sec_ary_int(i,j) /= 0 )
then
1626 &
'DC_SCALED_SEC must be smaller than 10^24' )
1628 if ( .not. sec_ary_int(i,j) < scale_factor )
then
1629 move_up =
int( sec_ary_int(i,j) / scale_factor_int )
1630 sec_ary_int(i,j) = sec_ary_int(i,j) - move_up * scale_factor_int
1637 result % sec_ary = 0
1640 if ( i + j < imin ) cycle
1641 if ( i + j > imax ) cycle
1642 result % sec_ary(i+j) = result % sec_ary(i+j) + sec_ary_int(i,j)
1648 result % sec_ary(i) = result % sec_ary(i) + move_up
1650 do while ( .not. result % sec_ary(i) < scale_factor_int )
1651 if ( i == imax )
then
1653 &
'DC_SCALED_SEC must be smaller than 10^24' )
1655 result % sec_ary(i) = result % sec_ary(i) - scale_factor_int
1656 move_up = move_up + 1
1660 end function dcscaledsec_mul_ss
1685 integer,
intent(in):: factor
1686 integer:: factor_abs
1688 real(dp):: sec_ary_dp(imin:imax)
1689 integer:: i, move_up
1691 if ( sclsec == zero_sec .or. factor == 0 )
then
1696 if ( sclsec % flag_negative )
then
1697 result % flag_negative = .not. factor < 0
1699 result % flag_negative = factor < 0
1701 factor_abs =
abs(factor)
1704 sec_ary_dp(:) = 0.0_dp
1706 sec_ary_dp(i) = sclsec % sec_ary(i) * factor_abs + move_up
1708 if ( .not. sec_ary_dp(i) < scale_factor )
then
1709 move_up =
int( sec_ary_dp(i) / scale_factor )
1710 sec_ary_dp(i) = sec_ary_dp(i) - move_up * scale_factor
1716 if ( move_up /= 0 )
then
1718 &
'DC_SCALED_SEC must be smaller than 10^24' )
1721 result % sec_ary(imin:imax) = nint( sec_ary_dp(imin:imax) )
1723 end function dcscaledsec_mul_si
1742 integer,
intent(in):: factor
1745 result = sclsec * factor
1746 end function dcscaledsec_mul_is
1767 real(dp),
intent(in):: factor
1771 result = sclsec * factor_scl
1772 end function dcscaledsec_mul_sd
1792 real(dp),
intent(in):: factor
1795 result = sclsec * factor
1796 end function dcscaledsec_mul_ds
1817 real,
intent(in):: factor
1821 result = sclsec * factor_scl
1822 end function dcscaledsec_mul_sr
1842 real,
intent(in):: factor
1845 result = sclsec * factor
1846 end function dcscaledsec_mul_rs
1873 real(dp):: factor_abs
1880 if ( .not. all( factor % sec_ary (imax-4:imax) == (/ 0, 0, 0, 0, 0 /) ) )
then
1882 &
'factor must be smaller than 10^12' )
1886 result = sclsec / factor_abs
1888 end function dcscaledsec_div_ss
1909 integer,
intent(in):: factor
1911 result = sclsec / real( factor, dp )
1912 end function dcscaledsec_div_si
1934 real(
dp),
intent(in):: factor
1936 real(
dp):: factor_abs, move_down, sec_ary_mod(imin+imin:imax)
1939 if ( sclsec % flag_negative )
then
1940 result % flag_negative = .not. factor < 0.0_dp
1942 result % flag_negative = factor < 0.0_dp
1944 factor_abs =
abs(factor) * scale_factor_xx(2)
1948 do i = imax, imax + imin + 1, -1
1949 sec_ary_mod(i) = sclsec % sec_ary(i)
1950 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
1951 move_down = sec_ary_mod(i) * scale_factor
1957 do i = imax + imin, imin, -1
1958 result % sec_ary(i-imin) =
int( ( sclsec % sec_ary(i) + move_down ) / factor_abs )
1960 &
mod( ( sclsec % sec_ary(i) + move_down ), factor_abs )
1961 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
1963 move_down = sec_ary_mod(i) * scale_factor
1969 do i = imin - 1, imin + imin, -1
1970 result % sec_ary(i-imin) =
int( move_down / factor_abs )
1971 sec_ary_mod(i) =
mod( move_down, factor_abs )
1972 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
1974 move_down = sec_ary_mod(i) * scale_factor
1985 end function dcscaledsec_div_sd
2006 real,
intent(in):: factor
2008 result = sclsec / real( factor,
dp )
2009 end function dcscaledsec_div_sr
2039 real(
dp):: sec_ary_mod(imin+imin:imax)
2040 integer:: i, move_down_index, sf_idx
2041 real(
dp):: move_down
2042 real(
dp):: factor_dp
2049 if ( .not. all( factor % sec_ary (imax-4:imax) == (/ 0, 0, 0, 0, 0 /) ) )
then
2051 &
'factor must be smaller than 10^12' )
2054 if ( sclsec == factor )
then
2059 factor_scl % sec_ary(imin:-1) = 0
2060 factor_scl % sec_ary(imin-imin:imax) = factor % sec_ary(imin:imax+imin)
2061 factor_scl % flag_negative = factor % flag_negative
2063 factor_dp = factor_scl
2067 do i = imax, imin, -1
2071 if ( sf_idx > ubound(scale_factor_xx, 1) ) sf_idx = ubound(scale_factor_xx, 1)
2072 if ( sf_idx < lbound(scale_factor_xx, 1) ) sf_idx = lbound(scale_factor_xx, 1)
2073 if (
abs(factor_dp) > ( move_down + scale_factor ) * scale_factor_xx( sf_idx ) )
then
2080 &
mod( ( sclsec % sec_ary(i) + move_down ), factor_dp )
2082 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
2083 move_down = sec_ary_mod(i) * scale_factor
2089 if ( .not. done )
then
2090 do i = imin - 1, imin + imin, -1
2094 if ( sf_idx > ubound(scale_factor_xx, 1) ) sf_idx = ubound(scale_factor_xx, 1)
2095 if ( sf_idx < lbound(scale_factor_xx, 1) ) sf_idx = lbound(scale_factor_xx, 1)
2096 if (
abs(factor_dp) > ( move_down + scale_factor ) * scale_factor_xx( sf_idx ) )
then
2102 sec_ary_mod(i) =
mod( move_down, factor_dp )
2104 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
2105 move_down = sec_ary_mod(i) * scale_factor
2112 result = move_down * scale_factor_xx(move_down_index)
2113 if ( move_down_index > imin - 1 )
then
2114 result % sec_ary(imin:move_down_index) = sclsec % sec_ary(imin:move_down_index)
2117 result % flag_negative = sclsec % flag_negative
2119 end function dcscaledsec_mod_ss
2140 integer,
intent(in):: factor
2145 result =
mod( sclsec, factor_scl )
2146 end function dcscaledsec_mod_si
2167 real,
intent(in):: factor
2172 result =
mod( sclsec, factor_scl )
2173 end function dcscaledsec_mod_sr
2194 real(
dp),
intent(in):: factor
2199 result =
mod( sclsec, factor_scl )
2200 end function dcscaledsec_mod_sd
2229 type(
dc_scaled_sec) function dcscaledsec_modulo_ss(sclsec, factor) result(result)
2236 real(
dp):: sec_ary_mod(imin+imin:imax)
2237 integer:: i, move_down_index, sf_idx
2238 real(
dp):: move_down
2239 real(
dp):: factor_dp
2246 if ( .not. all( factor % sec_ary (imax-4:imax) == (/ 0, 0, 0, 0, 0 /) ) )
then
2248 &
'factor must be smaller than 10^12' )
2251 if ( sclsec == factor )
then
2256 factor_scl % sec_ary(imin:-1) = 0
2257 factor_scl % sec_ary(imin-imin:imax) = factor % sec_ary(imin:imax+imin)
2258 factor_scl % flag_negative = factor % flag_negative
2260 factor_dp = factor_scl
2264 do i = imax, imin, -1
2268 if ( sf_idx > ubound(scale_factor_xx, 1) ) sf_idx = ubound(scale_factor_xx, 1)
2269 if ( sf_idx < lbound(scale_factor_xx, 1) ) sf_idx = lbound(scale_factor_xx, 1)
2270 if (
abs(factor_dp) > ( move_down + scale_factor ) * scale_factor_xx( sf_idx ) )
then
2277 &
mod( ( sclsec % sec_ary(i) + move_down ), factor_dp )
2279 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
2280 move_down = sec_ary_mod(i) * scale_factor
2286 if ( .not. done )
then
2287 do i = imin - 1, imin + imin, -1
2291 if ( sf_idx > ubound(scale_factor_xx, 1) ) sf_idx = ubound(scale_factor_xx, 1)
2292 if ( sf_idx < lbound(scale_factor_xx, 1) ) sf_idx = lbound(scale_factor_xx, 1)
2293 if (
abs(factor_dp) > ( move_down + scale_factor ) * scale_factor_xx( sf_idx ) )
then
2299 sec_ary_mod(i) =
mod( move_down, factor_dp )
2301 if (
abs(sec_ary_mod(i)) >
dp_eps )
then
2302 move_down = sec_ary_mod(i) * scale_factor
2309 result = move_down * scale_factor_xx(move_down_index)
2310 if ( move_down_index > imin - 1 )
then
2311 result % sec_ary(imin:move_down_index) = sclsec % sec_ary(imin:move_down_index)
2314 result % flag_negative = .false.
2316 if ( .not. result == zero_sec )
then
2317 if ( .not. sclsec % flag_negative .and. factor % flag_negative )
then
2318 result = - factor - result
2319 result % flag_negative = .not. sclsec % flag_negative
2321 elseif ( sclsec % flag_negative .and. .not. factor % flag_negative )
then
2322 result = factor - result
2323 result % flag_negative = .not. sclsec % flag_negative
2326 result % flag_negative = sclsec % flag_negative
2331 end function dcscaledsec_modulo_ss
2348 type(
dc_scaled_sec) function dcscaledsec_modulo_si(sclsec, factor) result(result)
2352 integer,
intent(in):: factor
2357 result =
modulo( sclsec, factor_scl )
2358 end function dcscaledsec_modulo_si
2375 type(
dc_scaled_sec) function dcscaledsec_modulo_sr(sclsec, factor) result(result)
2379 real,
intent(in):: factor
2384 result =
modulo( sclsec, factor_scl )
2385 end function dcscaledsec_modulo_sr
2402 type(
dc_scaled_sec) function dcscaledsec_modulo_sd(sclsec, factor) result(result)
2406 real(
dp),
intent(in):: factor
2411 result =
modulo( sclsec, factor_scl )
2412 end function dcscaledsec_modulo_sd
2433 if ( result % flag_negative ) result % flag_negative = .false.
2434 end function dcscaledsec_abs_s
2456 result % sec_ary(i) = 0
2458 end function dcscaledsec_int_s
2475 type(
dc_scaled_sec) function dcscaledsec_sign_ss(sclsec1, sclsec2) result(result)
2480 result % flag_negative = sclsec2 % flag_negative
2481 end function dcscaledsec_sign_ss
2501 integer,
intent(in):: factor
2504 sclsec_work = factor
2505 result =
sign( sclsec, sclsec_work )
2506 end function dcscaledsec_sign_si
2526 real,
intent(in):: factor
2529 sclsec_work = factor
2530 result =
sign( sclsec, sclsec_work )
2531 end function dcscaledsec_sign_sr
2551 real(
dp),
intent(in):: factor
2554 sclsec_work = factor
2555 result =
sign( sclsec, sclsec_work )
2556 end function dcscaledsec_sign_sd
2575 logical:: flag_after_decimal
2578 flag_after_decimal = .false.
2580 if ( result % sec_ary(i) /= 0 ) flag_after_decimal = .true.
2581 result % sec_ary(i) = 0
2583 if ( flag_after_decimal .and. result % flag_negative )
then
2587 end function dcscaledsec_floor_s
2606 logical:: flag_after_decimal
2609 flag_after_decimal = .false.
2611 if ( result % sec_ary(i) /= 0 ) flag_after_decimal = .true.
2612 result % sec_ary(i) = 0
2614 if ( flag_after_decimal .and. .not. result % flag_negative )
then
2618 end function dcscaledsec_ceiling_s
2640 function count_digit(sec)
result(result)
2642 integer,
intent(in):: sec
2649 if ( .not. sec < 10**i )
then
2656 end function count_digit
subroutine, public storeerror(number, where, err, cause_c, cause_i)
integer, parameter, public dc_noerr
Error storage variables
integer, parameter, public dc_etoolargetime
Scaled seconds module for precise time operations.
subroutine, public dcscaledsecputline(sclsec, unit, indent)
Handling character types.
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Provides kind type parameter values.
integer, parameter, public string
Character length for string
real(dp), parameter, public dp_eps
Machine epsilon for dobule precision real number.
integer, parameter, public stdout
Unit number for Standard OUTPUT
integer, parameter, public dp
Double Precision Real number