gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dc_scaledsec.f90
Go to the documentation of this file.
1! -*- mode: f90; coding: utf-8 -*-
2!-----------------------------------------------------------------------
3! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
4!-----------------------------------------------------------------------
5!>
6!> @author Youhei SASAKI, Yasuhiro MORIKAWA
7!> @copyright Copyright (C) GFD Dennou Club, 2008-2026. All rights reserved. <br/>
8!> License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
9!> @en
10!> @brief Scaled seconds module for precise time operations
11!> @details
12!> A module for correct operations of "seconds" after the decimal point,
13!> and large number more than integer type.
14!>
15!> This module provides the derived type DC_SCALED_SEC and operators for
16!> precise operations of time values that cannot be represented accurately
17!> by standard integer or real types.
18!>
19!> @section scaledsec_operators Operators and Procedures
20!>
21!> | Operator/Procedure | Description |
22!> |--------------------|--------------------------------------------------|
23!> | assignment(=) | Assignment |
24!> | operator(+) | Addition |
25!> | operator(-) | Subtraction |
26!> | operator(*) | Multiplication |
27!> | operator(/) | Division |
28!> | mod | Remainder |
29!> | modulo | Modulo |
30!> | operator(==) | Equal comparison |
31!> | operator(>) | Greater than comparison |
32!> | operator(<) | Less than comparison |
33!> | operator(>=) | Greater than or equal comparison |
34!> | operator(<=) | Less than or equal comparison |
35!> | abs | Absolute value |
36!> | int | Integer value (truncate fractional parts) |
37!> | sign | Set sign |
38!> | floor | Maximum integer not greater than given value |
39!> | ceiling | Minimum integer not less than given value |
40!>
41!> @enden
42!>
43!> @ja
44!> @brief 精密な時間演算のための秒スケールモジュール
45!> @details
46!> 小数点以下の「秒」や整数型では表現できない大きい数を
47!> 正確に演算するためのモジュールです.
48!>
49!> このモジュールは派生型 DC_SCALED_SEC と、標準の整数型や実数型では
50!> 正確に表現できない時間値を精密に演算するための演算子を提供します.
51!>
52!> @section scaledsec_operators_ja 演算子・手続一覧
53!>
54!> | 演算子/手続 | 説明 |
55!> |-------------|------------------------------------------------|
56!> | assignment(=) | 代入 |
57!> | operator(+) | 加算 |
58!> | operator(-) | 減算 |
59!> | operator(*) | 乗算 |
60!> | operator(/) | 除算 |
61!> | mod | 余り |
62!> | modulo | 剰余 |
63!> | operator(==) | 等値比較 |
64!> | operator(>) | 大なり比較 |
65!> | operator(<) | 小なり比較 |
66!> | operator(>=) | 以上比較 |
67!> | operator(<=) | 以下比較 |
68!> | abs | 絶対値の算出 |
69!> | int | 整数の算出 (小数点以下切捨て) |
70!> | sign | 符号の設定 |
71!> | floor | 整数の算出 (対象の数値以下で最大の整数) |
72!> | ceiling | 整数の算出 (対象の数値以上で最小の整数) |
73!>
74!> @endja
75!>
76
78 !
79 use dc_types, only: dp
80 implicit none
81 private
82
83 public:: dc_scaled_sec
84 public:: assignment(=), dcscaledsecputline
85 public:: operator(==), operator(>), operator(<), operator(>=), operator(<=)
86 public:: operator(+), operator(-), operator(*), operator(/), mod, modulo
87 public:: abs, int, sign, floor, ceiling
88
89!!$ integer, parameter:: imin = -1 ! 最小値の指数 = imin*6
90!!$ integer, parameter:: imax = 4 ! 最大値の指数 = imax*6
91!!$ real(DP), parameter:: scale_factor = 1.0e+6_DP
92!!$ integer, parameter:: scale_factor_int = 1000000
93 integer, parameter:: imin = -2 ! 最小値の指数 = imin*3
94 integer, parameter:: imax = 8 ! 最大値の指数 = imax*3
95 real(DP), parameter:: scale_factor = 1.0e+3_dp
96 real(DP), parameter:: scale_factor_xx (-(imax+1):imax+1) = &
97 & (/ 1.0e-27_DP, &
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, &
100 & 1.0_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, &
103 & 1.0e+27_DP /)
104
105 integer, parameter:: scale_factor_int = 1000
106 integer, parameter:: scale_factor_int_xx (0:3) = &
107 & (/ 1, 1000, 1000000, 1000000000 /)
108
109 !> @en
110 !> @brief Derived type for precise time operations
111 !> @details
112 !> Derived type for precise operations of "seconds" after
113 !> the decimal point, and large number more than integer type.
114 !>
115 !> The time value is stored in an array `sec_ary` with different
116 !> scale factors (from micro to yotta seconds).
117 !> @enden
118 !>
119 !> @ja
120 !> @brief 精密な時間演算のための派生型
121 !> @details
122 !> 小数点以下の「秒」や, 整数型では表現できないほど大きい数を
123 !> 正確に演算するための型.
124 !>
125 !> 時間値は異なるスケール係数(マイクロ秒からヨタ秒まで)を持つ
126 !> 配列 `sec_ary` に格納されます.
127 !> @endja
129 sequence
130 integer:: sec_ary(imin:imax) = 0 !< @en Array storing scaled seconds @enden @ja スケール化された秒を格納する配列 @endja
131 logical:: flag_negative = .false. !< @en Flag for negative value @enden @ja 負の値を示すフラグ @endja
132 logical:: dummy = .false. !< @en Dummy for alignment @enden @ja アラインメント用ダミー @endja
133 end type dc_scaled_sec
134
135 interface assignment(=)
136 module procedure dcscaledseccreater !:doc-priority 20:
137 module procedure dcscaledseccreated !:doc-priority 30:
138 module procedure dcscaledseccreatei !:doc-priority 40:
139
140 module procedure dcscaledsectonumr !:doc-priority 60:
141 module procedure dcscaledsectonumd !:doc-priority 70:
142 module procedure dcscaledsectonumi !:doc-priority 80:
143 end interface
144
145 interface putline
146 module procedure dcscaledsecputline
147 end interface
148
149 interface operator(==)
150 module procedure dcscaledsec_eq_ss !:doc-priority 20:
151 module procedure dcscaledsec_eq_si !:doc-priority 61:
152 module procedure dcscaledsec_eq_is !:doc-priority 62:
153 module procedure dcscaledsec_eq_sr !:doc-priority 63:
154 module procedure dcscaledsec_eq_rs !:doc-priority 64:
155 module procedure dcscaledsec_eq_sd !:doc-priority 65:
156 module procedure dcscaledsec_eq_ds !:doc-priority 66:
157 end interface
158
159 interface operator(>)
160 module procedure dcscaledsec_gt_ss
161 module procedure dcscaledsec_gt_si
162 module procedure dcscaledsec_gt_is
163 end interface
164
165 interface operator(<)
166 module procedure dcscaledsec_lt_ss
167 module procedure dcscaledsec_lt_si
168 module procedure dcscaledsec_lt_is
169 end interface
170
171 interface operator(>=)
172 module procedure dcscaledsec_ge_ss
173 module procedure dcscaledsec_ge_si
174 module procedure dcscaledsec_ge_is
175 end interface
176
177 interface operator(<=)
178 module procedure dcscaledsec_le_ss
179 module procedure dcscaledsec_le_si
180 module procedure dcscaledsec_le_is
181 end interface
182
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
191 end interface
192
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
202 end interface
203
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
212 end interface
213
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
219 end interface
220
221 interface mod
222 module procedure dcscaledsec_mod_si
223 module procedure dcscaledsec_mod_sr
224 module procedure dcscaledsec_mod_sd
225 module procedure dcscaledsec_mod_ss
226 end interface
227
228 interface modulo
229 module procedure dcscaledsec_modulo_si
230 module procedure dcscaledsec_modulo_sr
231 module procedure dcscaledsec_modulo_sd
232 module procedure dcscaledsec_modulo_ss
233 end interface
234
235 interface abs
236 module procedure dcscaledsec_abs_s
237 end interface
238
239 interface int
240 module procedure dcscaledsec_int_s
241 end interface
242
243 interface sign
244 module procedure dcscaledsec_sign_si
245 module procedure dcscaledsec_sign_sr
246 module procedure dcscaledsec_sign_sd
247 module procedure dcscaledsec_sign_ss
248 end interface
249
250 interface floor
251 module procedure dcscaledsec_floor_s
252 end interface
253
254 interface ceiling
255 module procedure dcscaledsec_ceiling_s
256 end interface
257
258contains
259
260 !-------------------------------------------------------------------
261
262 subroutine dcscaledseccreatei(sclsec, sec)
263 implicit none
264 type(dc_scaled_sec), intent(out):: sclsec
265 integer, intent(in):: sec
266 continue
267 call dcscaledseccreated(sclsec, real( sec, dp ))
268 end subroutine dcscaledseccreatei
269
270 !-------------------------------------------------------------------
271
272 subroutine dcscaledseccreater(sclsec, sec)
273 implicit none
274 type(dc_scaled_sec), intent(out):: sclsec
275 real, intent(in):: sec
276 continue
277 call dcscaledseccreated(sclsec, real( sec, dp ))
278 end subroutine dcscaledseccreater
279
280 !-------------------------------------------------------------------
281
282 subroutine dcscaledseccreated(sclsec, sec)
283 use dc_message, only: messagenotify
285 use dc_trace, only: beginsub, endsub
286 use dc_types, only: dp, string
287 implicit none
288 type(dc_scaled_sec), intent(out):: sclsec
289 real(DP), intent(in):: sec
290
291 real(DP):: work_sec, print_sec
292 integer:: i, cd, move_up, work_sec_scl_nint
293
294 integer :: stat
295 character(STRING) :: cause_c
296 character(*), parameter:: subname = 'dc_scaledsec'
297 continue
298 !call BeginSub(subname, 'sec=<%f>', d = (/ sec /) )
299 stat = dc_noerr
300 cause_c = ''
301
302 cd = 0
303 if ( sec < 0.0_dp ) then
304 sclsec % flag_negative = .true.
305 work_sec = - sec
306 else
307 sclsec % flag_negative = .false.
308 work_sec = sec
309 end if
310
311 if ( work_sec > scale_factor_xx(imax + 1) ) then
312 call messagenotify( 'W', subname, &
313 & 'input number (%f) is too large.', &
314 & d = (/ sec /) )
315 stat = dc_etoolargetime
316 goto 999
317 end if
318
319 sclsec % sec_ary = 0
320 do i = imax, imin, -1
321
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
325
326 if ( i < 0 ) then
327 sclsec % sec_ary(i) = work_sec_scl_nint
328 else
329 sclsec % sec_ary(i) = int( work_sec / scale_factor_xx(i) )
330 end if
331 work_sec = work_sec - sclsec % sec_ary(i) * scale_factor_xx(i)
332 cd = cd + count_digit( sclsec % sec_ary(i) )
333 end if
334 if ( cd > 5 ) then
335 if ( .not. abs( work_sec ) < scale_factor_xx(i-1) ) then
336 print_sec = sclsec
337!!$ call MessageNotify( 'W', subname, &
338!!$ & 'input number (%f) is truncated to (%f).', &
339!!$ & d = (/ sec, print_sec /) )
340 end if
341 exit
342 end if
343 end do
344
345 move_up = 0
346 do i = imin, imax
347 sclsec % sec_ary(i) = sclsec % sec_ary(i) + move_up
348 move_up = 0
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
352 end do
353 end do
354
355999 continue
356 call storeerror(stat, subname, cause_c=cause_c)
357 !call EndSub(subname)
358 end subroutine dcscaledseccreated
359
360 !-------------------------------------------------------------------
361
362 subroutine dcscaledsectonumi(sec, sclsec)
363 use dc_types, only: dp
364 implicit none
365 integer, intent(out):: sec
366 type(dc_scaled_sec), intent(in):: sclsec
367 real(DP):: secd
368 continue
369 call dcscaledsectonumd(secd, sclsec)
370 sec = nint( secd )
371 end subroutine dcscaledsectonumi
372
373 !-------------------------------------------------------------------
374
375 subroutine dcscaledsectonumr(sec, sclsec)
376 use dc_types, only: dp
377 implicit none
378 real, intent(out):: sec
379 type(dc_scaled_sec), intent(in):: sclsec
380 real(DP):: secd
381 continue
382 call dcscaledsectonumd(secd, sclsec)
383 sec = real( secd )
384 end subroutine dcscaledsectonumr
385
386 !-------------------------------------------------------------------
387
388 subroutine dcscaledsectonumd(sec, sclsec)
389 use dc_types, only: dp
390 implicit none
391 real(DP), intent(out):: sec
392 type(dc_scaled_sec), intent(in):: sclsec
393
394 integer:: i
395 continue
396 sec = 0.0_dp
397 do i = imax, imin, -1
398 sec = sec + ( sclsec % sec_ary(i) * scale_factor_xx(i) )
399 end do
400 if ( sclsec % flag_negative ) sec = - sec
401 end subroutine dcscaledsectonumd
402
403 !-------------------------------------------------------------------
404
405 !> @en
406 !> @brief Print information of DC_SCALED_SEC
407 !> @details
408 !> Print information of `sclsec`.
409 !> By default messages are output to standard output.
410 !> Unit number for output can be changed by `unit` argument.
411 !>
412 !> @param[in] sclsec DC_SCALED_SEC variable to print
413 !> @param[in] unit Unit number for output. Default is standard output.
414 !> @param[in] indent Indent string for displayed messages
415 !> @enden
416 !>
417 !> @ja
418 !> @brief DC_SCALED_SEC の情報を印字
419 !> @details
420 !> 引数 `sclsec` に設定されている情報を印字します.
421 !> デフォルトではメッセージは標準出力に出力されます.
422 !> `unit` に装置番号を指定することで, 出力先を変更することが可能です.
423 !>
424 !> @param[in] sclsec 印字する DC_SCALED_SEC 型変数
425 !> @param[in] unit 出力先の装置番号. デフォルトは標準出力.
426 !> @param[in] indent 表示されるメッセージの字下げ
427 !> @endja
428 subroutine dcscaledsecputline( sclsec, unit, indent )
429 use dc_string, only: printf, tochar
430 use dc_trace, only: beginsub, endsub
431 use dc_types, only: stdout, string
432 implicit none
433 type(dc_scaled_sec), intent(in) :: sclsec
434 integer, intent(in), optional :: unit
435 character(*), intent(in), optional:: indent
436
437 integer :: out_unit, sec_ary_rev(imin:imax)
438 integer:: indent_len
439 character(STRING):: indent_str
440 character(1):: sign
441 continue
442 !call BeginSub(subname)
443
444 if (present(unit)) then
445 out_unit = unit
446 else
447 out_unit = stdout
448 end if
449
450 indent_len = 0
451 indent_str = ''
452 if ( present(indent) ) then
453 if ( len(indent) /= 0 ) then
454 indent_len = len(indent)
455 indent_str(1:indent_len) = indent
456 end if
457 end if
458
459 sec_ary_rev(imin:imax) = sclsec % sec_ary(imax:imin:-1)
460 if ( sclsec % flag_negative ) then
461 sign = '-'
462 else
463 sign = '+'
464 end if
465 if ( imax - imin + 1 == 6 ) then
466 call printf(out_unit, &
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
471 call printf(out_unit, &
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 )
475 call printf(out_unit, &
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) )
479 else
480 call printf(out_unit, &
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 )
484 end if
485 !call EndSub(subname)
486 end subroutine dcscaledsecputline
487
488 !-------------------------------------------------------------------
489
490 !> @en
491 !> @brief Compare two DC_SCALED_SEC variables for equality
492 !> @param[in] sclsec1 First DC_SCALED_SEC variable
493 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
494 !> @return .true. if equal, .false. otherwise
495 !> @enden
496 !>
497 !> @ja
498 !> @brief 2つの DC_SCALED_SEC 型変数の等値比較
499 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
500 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
501 !> @return 等しければ .true., そうでなければ .false.
502 !> @endja
503 logical function dcscaledsec_eq_ss(sclsec1, sclsec2) result(result)
504 implicit none
505 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
506
507 integer:: i
508 continue
509 if ( sclsec1 % flag_negative .and. .not. sclsec2 % flag_negative ) then
510 result = .false.
511
512 return
513 elseif ( .not. sclsec1 % flag_negative .and. sclsec2 % flag_negative ) then
514 result = .false.
515 return
516 end if
517
518 do i = imax, imin, -1
519 if ( .not. sclsec1 % sec_ary(i) == sclsec2 % sec_ary(i) ) then
520 result = .false.
521 return
522 end if
523 end do
524
525 result = .true.
526 end function dcscaledsec_eq_ss
527
528 !-------------------------------------------------------------------
529
530 logical function dcscaledsec_eq_si(sclsec, sec) result(result)
531 implicit none
532 type(dc_scaled_sec), intent(in):: sclsec
533 integer, intent(in):: sec
534 type(dc_scaled_sec):: sclsec2
535 integer:: i, sec1
536 continue
537 if ( sclsec % flag_negative .and. .not. sec < 0 ) then
538 result = .false.
539 return
540 elseif ( .not. sclsec % flag_negative .and. sec < 0 ) then
541 result = .false.
542 return
543 end if
544
545 if ( abs(sec) > scale_factor_int_xx(3) ) then
546 sclsec2 = sec
547 result = sclsec == sclsec2
548 else
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
551 result = .false.
552 return
553 end if
554 sec1 = sclsec % sec_ary(0)
555 do i = 1, 2
556 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
557 end do
558 result = sec1 == sec
559 end if
560 end function dcscaledsec_eq_si
561
562 !-------------------------------------------------------------------
563
564 logical function dcscaledsec_eq_is(sec, sclsec) result(result)
565 implicit none
566 integer, intent(in):: sec
567 type(dc_scaled_sec), intent(in):: sclsec
568 continue
569 result = sclsec == sec
570 end function dcscaledsec_eq_is
571
572 !-------------------------------------------------------------------
573
574 logical function dcscaledsec_eq_sr(sclsec, sec) result(result)
575 implicit none
576 type(dc_scaled_sec), intent(in):: sclsec
577 real, intent(in):: sec
578 type(dc_scaled_sec):: sclsec2
579 continue
580 sclsec2 = sec
581 result = sclsec == sclsec2
582 end function dcscaledsec_eq_sr
583
584 !-------------------------------------------------------------------
585
586 logical function dcscaledsec_eq_rs(sec, sclsec) result(result)
587 implicit none
588 real, intent(in):: sec
589 type(dc_scaled_sec), intent(in):: sclsec
590 type(dc_scaled_sec):: sclsec2
591 continue
592 sclsec2 = sec
593 result = sclsec == sclsec2
594 end function dcscaledsec_eq_rs
595
596 !-------------------------------------------------------------------
597
598 logical function dcscaledsec_eq_sd(sclsec, sec) result(result)
599 implicit none
600 type(dc_scaled_sec), intent(in):: sclsec
601 real(dp), intent(in):: sec
602 type(dc_scaled_sec):: sclsec2
603 continue
604 sclsec2 = sec
605 result = sclsec == sclsec2
606 end function dcscaledsec_eq_sd
607
608 !-------------------------------------------------------------------
609
610 logical function dcscaledsec_eq_ds(sec, sclsec) result(result)
611 implicit none
612 real(dp), intent(in):: sec
613 type(dc_scaled_sec), intent(in):: sclsec
614 type(dc_scaled_sec):: sclsec2
615 continue
616 sclsec2 = sec
617 result = sclsec == sclsec2
618 end function dcscaledsec_eq_ds
619
620 !-------------------------------------------------------------------
621
622 !> @en
623 !> @brief Compare two DC_SCALED_SEC variables (greater than)
624 !> @param[in] sclsec1 First DC_SCALED_SEC variable
625 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
626 !> @return .true. if sclsec1 > sclsec2, .false. otherwise
627 !> @enden
628 !>
629 !> @ja
630 !> @brief 2つの DC_SCALED_SEC 型変数の大なり比較
631 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
632 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
633 !> @return sclsec1 > sclsec2 なら .true., そうでなければ .false.
634 !> @endja
635 logical function dcscaledsec_gt_ss(sclsec1, sclsec2) result(result)
636 implicit none
637 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
638
639 integer:: i
640 logical:: both_negative, flag_equal
641 continue
642 result = .false.
643 flag_equal = .true.
644
645 if ( sclsec1 % flag_negative .and. .not. sclsec2 % flag_negative ) then
646 result = .false.
647 return
648 elseif ( .not. sclsec1 % flag_negative .and. sclsec2 % flag_negative ) then
649 result = .true.
650 return
651 elseif ( sclsec1 % flag_negative .and. sclsec2 % flag_negative ) then
652 both_negative = .true.
653 else
654 both_negative = .false.
655 end if
656
657 do i = imax, imin, -1
658 if ( sclsec1 % sec_ary(i) > sclsec2 % sec_ary(i) ) then
659 result = .true.
660 flag_equal = .false.
661 exit
662 elseif ( sclsec1 % sec_ary(i) < sclsec2 % sec_ary(i) ) then
663 result = .false.
664 flag_equal = .false.
665 exit
666 end if
667 end do
668
669 if ( .not. flag_equal .and. both_negative ) result = .not. result
670
671 end function dcscaledsec_gt_ss
672
673 !-------------------------------------------------------------------
674
675 !> @en
676 !> @brief Compare DC_SCALED_SEC with integer (greater than)
677 !> @param[in] sclsec DC_SCALED_SEC variable
678 !> @param[in] factor Integer value to compare
679 !> @return .true. if sclsec > factor, .false. otherwise
680 !> @enden
681 !>
682 !> @ja
683 !> @brief DC_SCALED_SEC と整数の大なり比較
684 !> @param[in] sclsec DC_SCALED_SEC 型変数
685 !> @param[in] factor 比較する整数値
686 !> @return sclsec > factor なら .true., そうでなければ .false.
687 !> @endja
688 logical function dcscaledsec_gt_si(sclsec, factor) result(result)
689 implicit none
690 type(dc_scaled_sec), intent(in):: sclsec
691 integer, intent(in):: factor
692 type(dc_scaled_sec):: factor_scl
693 integer:: i, sec1, factor_abs
694 logical:: both_negative
695 continue
696 if ( sclsec % flag_negative .and. .not. factor < 0 ) then
697 result = .false.
698 return
699 elseif ( .not. sclsec % flag_negative .and. factor < 0 ) then
700 result = .true.
701 return
702 elseif ( sclsec % flag_negative .and. factor < 0 ) then
703 both_negative = .true.
704 else
705 both_negative = .false.
706 end if
707
708 factor_abs = abs(factor)
709
710 if ( factor_abs > scale_factor_int_xx(3) ) then
711 factor_scl = factor
712 result = sclsec > factor_scl
713 return
714 else
715 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) ) then
716 result = .true.
717 else
718 sec1 = sclsec % sec_ary(0)
719 do i = 1, 2
720 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
721 end do
722 if ( sec1 == factor_abs ) then
723 result = .not. all( sclsec % sec_ary(imin:-1) == (/0, 0/) )
724 else
725 result = sec1 > factor_abs
726 end if
727 end if
728
729 if ( both_negative ) result = .not. result
730 end if
731
732 end function dcscaledsec_gt_si
733
734 !-------------------------------------------------------------------
735
736 !> @en
737 !> @brief Compare integer with DC_SCALED_SEC (greater than)
738 !> @param[in] factor Integer value to compare
739 !> @param[in] sclsec DC_SCALED_SEC variable
740 !> @return .true. if factor > sclsec, .false. otherwise
741 !> @enden
742 !>
743 !> @ja
744 !> @brief 整数と DC_SCALED_SEC の大なり比較
745 !> @param[in] factor 比較する整数値
746 !> @param[in] sclsec DC_SCALED_SEC 型変数
747 !> @return factor > sclsec なら .true., そうでなければ .false.
748 !> @endja
749 logical function dcscaledsec_gt_is(factor, sclsec) result(result)
750 implicit none
751 integer, intent(in):: factor
752 type(dc_scaled_sec), intent(in):: sclsec
753 type(dc_scaled_sec):: factor_scl
754 integer:: i, sec1, factor_abs
755 logical:: both_negative
756 continue
757 if ( sclsec % flag_negative .and. .not. factor < 0 ) then
758 result = .true.
759 return
760 elseif ( .not. sclsec % flag_negative .and. factor < 0 ) then
761 result = .false.
762 return
763 elseif ( sclsec % flag_negative .and. factor < 0 ) then
764 both_negative = .true.
765 else
766 both_negative = .false.
767 end if
768
769 factor_abs = abs(factor)
770
771 if ( factor_abs > scale_factor_int_xx(3) ) then
772 factor_scl = factor
773 result = factor_scl > sclsec
774 return
775 else
776 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) ) then
777 result = .false.
778 else
779 sec1 = sclsec % sec_ary(0)
780 do i = 1, 2
781 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
782 end do
783 if ( sec1 == factor_abs ) then
784 result = .false.
785 else
786 result = factor_abs > sec1
787 end if
788 end if
789
790 if ( both_negative ) result = .not. result
791 end if
792 end function dcscaledsec_gt_is
793
794 !-------------------------------------------------------------------
795
796 !> @en
797 !> @brief Compare two DC_SCALED_SEC variables (less than)
798 !> @param[in] sclsec1 First DC_SCALED_SEC variable
799 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
800 !> @return .true. if sclsec1 < sclsec2, .false. otherwise
801 !> @enden
802 !>
803 !> @ja
804 !> @brief 2つの DC_SCALED_SEC 型変数の小なり比較
805 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
806 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
807 !> @return sclsec1 < sclsec2 なら .true., そうでなければ .false.
808 !> @endja
809 logical function dcscaledsec_lt_ss(sclsec1, sclsec2) result(result)
810 implicit none
811 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
812 integer:: i
813 logical:: both_negative, flag_equal
814 continue
815 result = .false.
816 flag_equal = .true.
817
818 if ( sclsec1 % flag_negative .and. .not. sclsec2 % flag_negative ) then
819 result = .true.
820 return
821 elseif ( .not. sclsec1 % flag_negative .and. sclsec2 % flag_negative ) then
822 result = .false.
823 return
824 elseif ( sclsec1 % flag_negative .and. sclsec2 % flag_negative ) then
825 both_negative = .true.
826 else
827 both_negative = .false.
828 end if
829
830 do i = imax, imin, -1
831 if ( sclsec1 % sec_ary(i) > sclsec2 % sec_ary(i) ) then
832 result = .false.
833 flag_equal = .false.
834 exit
835 elseif ( sclsec1 % sec_ary(i) < sclsec2 % sec_ary(i) ) then
836 result = .true.
837 flag_equal = .false.
838 exit
839 end if
840 end do
841
842 if ( .not. flag_equal .and. both_negative ) result = .not. result
843
844 end function dcscaledsec_lt_ss
845
846 !-------------------------------------------------------------------
847
848 !> @en
849 !> @brief Compare DC_SCALED_SEC with integer (less than)
850 !> @param[in] sclsec DC_SCALED_SEC variable
851 !> @param[in] factor Integer value to compare
852 !> @return .true. if sclsec < factor, .false. otherwise
853 !> @enden
854 !>
855 !> @ja
856 !> @brief DC_SCALED_SEC と整数の小なり比較
857 !> @param[in] sclsec DC_SCALED_SEC 型変数
858 !> @param[in] factor 比較する整数値
859 !> @return sclsec < factor なら .true., そうでなければ .false.
860 !> @endja
861 logical function dcscaledsec_lt_si(sclsec, factor) result(result)
862 implicit none
863 type(dc_scaled_sec), intent(in):: sclsec
864 integer, intent(in):: factor
865 type(dc_scaled_sec):: factor_scl
866 integer:: i, sec1, factor_abs
867 logical:: both_negative
868 continue
869 if ( sclsec % flag_negative .and. .not. factor < 0 ) then
870 result = .true.
871 return
872 elseif ( .not. sclsec % flag_negative .and. factor < 0 ) then
873 result = .false.
874 return
875 elseif ( sclsec % flag_negative .and. factor < 0 ) then
876 both_negative = .true.
877 else
878 both_negative = .false.
879 end if
880
881 factor_abs = abs(factor)
882
883 if ( factor_abs > scale_factor_int_xx(3) ) then
884 factor_scl = factor
885 result = sclsec < factor_scl
886 return
887 else
888 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) ) then
889 result = .false.
890 else
891 sec1 = sclsec % sec_ary(0)
892 do i = 1, 2
893 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
894 end do
895 if ( sec1 == factor_abs ) then
896 result = .false.
897 else
898 result = sec1 < factor_abs
899 end if
900 end if
901
902 if ( both_negative ) result = .not. result
903 end if
904 end function dcscaledsec_lt_si
905
906 !-------------------------------------------------------------------
907
908 !> @en
909 !> @brief Compare integer with DC_SCALED_SEC (less than)
910 !> @param[in] factor Integer value to compare
911 !> @param[in] sclsec DC_SCALED_SEC variable
912 !> @return .true. if factor < sclsec, .false. otherwise
913 !> @enden
914 !>
915 !> @ja
916 !> @brief 整数と DC_SCALED_SEC の小なり比較
917 !> @param[in] factor 比較する整数値
918 !> @param[in] sclsec DC_SCALED_SEC 型変数
919 !> @return factor < sclsec なら .true., そうでなければ .false.
920 !> @endja
921 logical function dcscaledsec_lt_is(factor, sclsec) result(result)
922 implicit none
923 integer, intent(in):: factor
924 type(dc_scaled_sec), intent(in):: sclsec
925 type(dc_scaled_sec):: factor_scl
926 integer:: i, sec1, factor_abs
927 logical:: both_negative
928 continue
929 if ( sclsec % flag_negative .and. .not. factor < 0 ) then
930 result = .false.
931 return
932 elseif ( .not. sclsec % flag_negative .and. factor < 0 ) then
933 result = .true.
934 return
935 elseif ( sclsec % flag_negative .and. factor < 0 ) then
936 both_negative = .true.
937 else
938 both_negative = .false.
939 end if
940
941 factor_abs = abs(factor)
942
943 if ( factor_abs > scale_factor_int_xx(3) ) then
944 factor_scl = factor
945 result = factor_scl < sclsec
946 return
947 else
948 if ( .not. all( sclsec % sec_ary(3:imax) == (/0, 0, 0, 0, 0, 0/) ) ) then
949 result = .true.
950 else
951 sec1 = sclsec % sec_ary(0)
952 do i = 1, 2
953 sec1 = sec1 + sclsec % sec_ary(i) * scale_factor_int_xx(i)
954 end do
955 if ( sec1 == factor_abs ) then
956 result = .not. all( sclsec % sec_ary(imin:-1) == (/0, 0/) )
957 else
958 result = factor_abs < sec1
959 end if
960 end if
961
962 if ( both_negative ) result = .not. result
963 end if
964
965 end function dcscaledsec_lt_is
966
967 !-------------------------------------------------------------------
968
969 !> @en
970 !> @brief Compare two DC_SCALED_SEC variables (greater or equal)
971 !> @param[in] sclsec1 First DC_SCALED_SEC variable
972 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
973 !> @return .true. if sclsec1 >= sclsec2, .false. otherwise
974 !> @enden
975 !>
976 !> @ja
977 !> @brief 2つの DC_SCALED_SEC 型変数の以上比較
978 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
979 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
980 !> @return sclsec1 >= sclsec2 なら .true., そうでなければ .false.
981 !> @endja
982 logical function dcscaledsec_ge_ss(sclsec1, sclsec2) result(result)
983 implicit none
984 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
985 continue
986 result = .not. sclsec1 < sclsec2
987 end function dcscaledsec_ge_ss
988
989 !-------------------------------------------------------------------
990
991 !> @en
992 !> @brief Compare DC_SCALED_SEC with integer (greater or equal)
993 !> @param[in] sclsec DC_SCALED_SEC variable
994 !> @param[in] factor Integer value to compare
995 !> @return .true. if sclsec >= factor, .false. otherwise
996 !> @enden
997 !>
998 !> @ja
999 !> @brief DC_SCALED_SEC と整数の以上比較
1000 !> @param[in] sclsec DC_SCALED_SEC 型変数
1001 !> @param[in] factor 比較する整数値
1002 !> @return sclsec >= factor なら .true., そうでなければ .false.
1003 !> @endja
1004 logical function dcscaledsec_ge_si(sclsec, factor) result(result)
1005 implicit none
1006 type(dc_scaled_sec), intent(in):: sclsec
1007 integer, intent(in):: factor
1008 continue
1009 result = .not. sclsec < factor
1010 end function dcscaledsec_ge_si
1011
1012 !-------------------------------------------------------------------
1013
1014 !> @en
1015 !> @brief Compare integer with DC_SCALED_SEC (greater or equal)
1016 !> @param[in] factor Integer value to compare
1017 !> @param[in] sclsec DC_SCALED_SEC variable
1018 !> @return .true. if factor >= sclsec, .false. otherwise
1019 !> @enden
1020 !>
1021 !> @ja
1022 !> @brief 整数と DC_SCALED_SEC の以上比較
1023 !> @param[in] factor 比較する整数値
1024 !> @param[in] sclsec DC_SCALED_SEC 型変数
1025 !> @return factor >= sclsec なら .true., そうでなければ .false.
1026 !> @endja
1027 logical function dcscaledsec_ge_is(factor, sclsec) result(result)
1028 implicit none
1029 integer, intent(in):: factor
1030 type(dc_scaled_sec), intent(in):: sclsec
1031 continue
1032 result = .not. factor < sclsec
1033 end function dcscaledsec_ge_is
1034
1035 !-------------------------------------------------------------------
1036
1037 !> @en
1038 !> @brief Compare two DC_SCALED_SEC variables (less or equal)
1039 !> @param[in] sclsec1 First DC_SCALED_SEC variable
1040 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
1041 !> @return .true. if sclsec1 <= sclsec2, .false. otherwise
1042 !> @enden
1043 !>
1044 !> @ja
1045 !> @brief 2つの DC_SCALED_SEC 型変数の以下比較
1046 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
1047 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
1048 !> @return sclsec1 <= sclsec2 なら .true., そうでなければ .false.
1049 !> @endja
1050 logical function dcscaledsec_le_ss(sclsec1, sclsec2) result(result)
1051 implicit none
1052 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
1053 continue
1054 result = .not. sclsec1 > sclsec2
1055 end function dcscaledsec_le_ss
1056
1057 !-------------------------------------------------------------------
1058
1059 !> @en
1060 !> @brief Compare DC_SCALED_SEC with integer (less or equal)
1061 !> @param[in] sclsec DC_SCALED_SEC variable
1062 !> @param[in] factor Integer value to compare
1063 !> @return .true. if sclsec <= factor, .false. otherwise
1064 !> @enden
1065 !>
1066 !> @ja
1067 !> @brief DC_SCALED_SEC と整数の以下比較
1068 !> @param[in] sclsec DC_SCALED_SEC 型変数
1069 !> @param[in] factor 比較する整数値
1070 !> @return sclsec <= factor なら .true., そうでなければ .false.
1071 !> @endja
1072 logical function dcscaledsec_le_si(sclsec, factor) result(result)
1073 implicit none
1074 type(dc_scaled_sec), intent(in):: sclsec
1075 integer, intent(in):: factor
1076 continue
1077 result = .not. sclsec > factor
1078 end function dcscaledsec_le_si
1079
1080 !-------------------------------------------------------------------
1081
1082 !> @en
1083 !> @brief Compare integer with DC_SCALED_SEC (less or equal)
1084 !> @param[in] factor Integer value to compare
1085 !> @param[in] sclsec DC_SCALED_SEC variable
1086 !> @return .true. if factor <= sclsec, .false. otherwise
1087 !> @enden
1088 !>
1089 !> @ja
1090 !> @brief 整数と DC_SCALED_SEC の以下比較
1091 !> @param[in] factor 比較する整数値
1092 !> @param[in] sclsec DC_SCALED_SEC 型変数
1093 !> @return factor <= sclsec なら .true., そうでなければ .false.
1094 !> @endja
1095 logical function dcscaledsec_le_is(factor, sclsec) result(result)
1096 implicit none
1097 integer, intent(in):: factor
1098 type(dc_scaled_sec), intent(in):: sclsec
1099 continue
1100 result = .not. factor > sclsec
1101 end function dcscaledsec_le_is
1102
1103 !-------------------------------------------------------------------
1104
1105 !> @en
1106 !> @brief Add two DC_SCALED_SEC variables
1107 !> @param[in] sclsec1 First DC_SCALED_SEC variable
1108 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
1109 !> @return Sum of two DC_SCALED_SEC variables
1110 !> @enden
1111 !>
1112 !> @ja
1113 !> @brief 2つの DC_SCALED_SEC 型変数の加算
1114 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
1115 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
1116 !> @return 2つの DC_SCALED_SEC 型変数の和
1117 !> @endja
1118 type(dc_scaled_sec) function dcscaledsec_add_ss(sclsec1, sclsec2) result(result)
1119 use dc_message, only: messagenotify
1120 implicit none
1121 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
1122
1123 integer:: i, move_up
1124 logical:: both_negative, sclsec2_flag_negative
1125 type(dc_scaled_sec):: sclsec1_opsign, sclsec2_opsign
1126 continue
1127 move_up = 0
1128 both_negative = .false.
1129
1130 ! 負の値の処理
1131 ! Handle negative value
1132 !
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
1137 end if
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
1146 end if
1147 return
1148 end if
1149
1150 ! 加算
1151 ! Addition
1152 !
1153 do i = imin, imax
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
1157 call messagenotify( 'E', 'dc_scaledsec#operator(*)', &
1158 & 'DC_SCALED_SEC must be smaller than 10^24' )
1159 end if
1160 move_up = result % sec_ary(i) / scale_factor_int
1161 result % sec_ary(i) = mod( result % sec_ary(i), scale_factor_int )
1162 else
1163 move_up = 0
1164 end if
1165 end do
1166
1167 if ( both_negative ) then
1168 result % flag_negative = .true.
1169 else
1170 result % flag_negative = .false.
1171 end if
1172
1173 end function dcscaledsec_add_ss
1174
1175 !-------------------------------------------------------------------
1176
1177 !> @en
1178 !> @brief Add DC_SCALED_SEC and integer
1179 !> @param[in] sclsec DC_SCALED_SEC variable
1180 !> @param[in] factor Integer value to add
1181 !> @return Sum of DC_SCALED_SEC and integer
1182 !> @enden
1183 !>
1184 !> @ja
1185 !> @brief DC_SCALED_SEC と整数の加算
1186 !> @param[in] sclsec DC_SCALED_SEC 型変数
1187 !> @param[in] factor 加算する整数値
1188 !> @return DC_SCALED_SEC と整数の和
1189 !> @endja
1190 type(dc_scaled_sec) function dcscaledsec_add_si(sclsec, factor) result(result)
1191 implicit none
1192 type(dc_scaled_sec), intent(in):: sclsec
1193 integer, intent(in):: factor
1194 type(dc_scaled_sec):: factor_scl
1195 continue
1196 factor_scl = factor
1197 result = sclsec + factor_scl
1198 end function dcscaledsec_add_si
1199
1200 !-------------------------------------------------------------------
1201
1202 !> @en
1203 !> @brief Add integer and DC_SCALED_SEC
1204 !> @param[in] factor Integer value to add
1205 !> @param[in] sclsec DC_SCALED_SEC variable
1206 !> @return Sum of integer and DC_SCALED_SEC
1207 !> @enden
1208 !>
1209 !> @ja
1210 !> @brief 整数と DC_SCALED_SEC の加算
1211 !> @param[in] factor 加算する整数値
1212 !> @param[in] sclsec DC_SCALED_SEC 型変数
1213 !> @return 整数と DC_SCALED_SEC の和
1214 !> @endja
1215 type(dc_scaled_sec) function dcscaledsec_add_is(factor, sclsec) result(result)
1216 implicit none
1217 integer, intent(in):: factor
1218 type(dc_scaled_sec), intent(in):: sclsec
1219 type(dc_scaled_sec):: factor_scl
1220 continue
1221 factor_scl = factor
1222 result = factor_scl + sclsec
1223 end function dcscaledsec_add_is
1224
1225 !-------------------------------------------------------------------
1226
1227 !> @en
1228 !> @brief Add DC_SCALED_SEC and single precision real
1229 !> @param[in] sclsec DC_SCALED_SEC variable
1230 !> @param[in] factor Real value to add
1231 !> @return Sum of DC_SCALED_SEC and real
1232 !> @enden
1233 !>
1234 !> @ja
1235 !> @brief DC_SCALED_SEC と単精度実数の加算
1236 !> @param[in] sclsec DC_SCALED_SEC 型変数
1237 !> @param[in] factor 加算する実数値
1238 !> @return DC_SCALED_SEC と実数の和
1239 !> @endja
1240 type(dc_scaled_sec) function dcscaledsec_add_sr(sclsec, factor) result(result)
1241 implicit none
1242 type(dc_scaled_sec), intent(in):: sclsec
1243 real, intent(in):: factor
1244 type(dc_scaled_sec):: factor_scl
1245 continue
1246 factor_scl = factor
1247 result = sclsec + factor_scl
1248 end function dcscaledsec_add_sr
1249
1250 !-------------------------------------------------------------------
1251
1252 !> @en
1253 !> @brief Add single precision real and DC_SCALED_SEC
1254 !> @param[in] factor Real value to add
1255 !> @param[in] sclsec DC_SCALED_SEC variable
1256 !> @return Sum of real and DC_SCALED_SEC
1257 !> @enden
1258 !>
1259 !> @ja
1260 !> @brief 単精度実数と DC_SCALED_SEC の加算
1261 !> @param[in] factor 加算する実数値
1262 !> @param[in] sclsec DC_SCALED_SEC 型変数
1263 !> @return 実数と DC_SCALED_SEC の和
1264 !> @endja
1265 type(dc_scaled_sec) function dcscaledsec_add_rs(factor, sclsec) result(result)
1266 implicit none
1267 real, intent(in):: factor
1268 type(dc_scaled_sec), intent(in):: sclsec
1269 type(dc_scaled_sec):: factor_scl
1270 continue
1271 factor_scl = factor
1272 result = sclsec + factor_scl
1273 end function dcscaledsec_add_rs
1274
1275 !-------------------------------------------------------------------
1276
1277 !> @en
1278 !> @brief Add DC_SCALED_SEC and double precision real
1279 !> @param[in] sclsec DC_SCALED_SEC variable
1280 !> @param[in] factor Double precision value to add
1281 !> @return Sum of DC_SCALED_SEC and double
1282 !> @enden
1283 !>
1284 !> @ja
1285 !> @brief DC_SCALED_SEC と倍精度実数の加算
1286 !> @param[in] sclsec DC_SCALED_SEC 型変数
1287 !> @param[in] factor 加算する倍精度実数値
1288 !> @return DC_SCALED_SEC と倍精度実数の和
1289 !> @endja
1290 type(dc_scaled_sec) function dcscaledsec_add_sd(sclsec, factor) result(result)
1291 implicit none
1292 type(dc_scaled_sec), intent(in):: sclsec
1293 real(dp), intent(in):: factor
1294 type(dc_scaled_sec):: factor_scl
1295 continue
1296 factor_scl = factor
1297 result = sclsec + factor_scl
1298 end function dcscaledsec_add_sd
1299
1300 !-------------------------------------------------------------------
1301
1302 !> @en
1303 !> @brief Add double precision real and DC_SCALED_SEC
1304 !> @param[in] factor Double precision value to add
1305 !> @param[in] sclsec DC_SCALED_SEC variable
1306 !> @return Sum of double and DC_SCALED_SEC
1307 !> @enden
1308 !>
1309 !> @ja
1310 !> @brief 倍精度実数と DC_SCALED_SEC の加算
1311 !> @param[in] factor 加算する倍精度実数値
1312 !> @param[in] sclsec DC_SCALED_SEC 型変数
1313 !> @return 倍精度実数と DC_SCALED_SEC の和
1314 !> @endja
1315 type(dc_scaled_sec) function dcscaledsec_add_ds(factor, sclsec) result(result)
1316 implicit none
1317 real(dp), intent(in):: factor
1318 type(dc_scaled_sec), intent(in):: sclsec
1319 type(dc_scaled_sec):: factor_scl
1320 continue
1321 factor_scl = factor
1322 result = sclsec + factor_scl
1323 end function dcscaledsec_add_ds
1324
1325 !-------------------------------------------------------------------
1326
1327 !> @en
1328 !> @brief Negate DC_SCALED_SEC (unary minus)
1329 !> @param[in] sclsec DC_SCALED_SEC variable
1330 !> @return Negated DC_SCALED_SEC variable
1331 !> @enden
1332 !>
1333 !> @ja
1334 !> @brief DC_SCALED_SEC の符号反転 (単項マイナス)
1335 !> @param[in] sclsec DC_SCALED_SEC 型変数
1336 !> @return 符号を逆にした DC_SCALED_SEC 型変数
1337 !> @endja
1338 type(dc_scaled_sec) function dcscaledsec_sub_s(sclsec) result(result)
1339 implicit none
1340 type(dc_scaled_sec), intent(in):: sclsec
1341 continue
1342 result % flag_negative = .not. sclsec % flag_negative
1343 result % sec_ary = sclsec % sec_ary
1344 end function dcscaledsec_sub_s
1345
1346 !-------------------------------------------------------------------
1347
1348 !> @en
1349 !> @brief Subtract two DC_SCALED_SEC variables
1350 !> @param[in] sclsec1 First DC_SCALED_SEC variable
1351 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
1352 !> @return Difference of two DC_SCALED_SEC variables
1353 !> @enden
1354 !>
1355 !> @ja
1356 !> @brief 2つの DC_SCALED_SEC 型変数の減算
1357 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
1358 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
1359 !> @return 2つの DC_SCALED_SEC 型変数の差
1360 !> @endja
1361 type(dc_scaled_sec) function dcscaledsec_sub_ss(sclsec1, sclsec2) result(result)
1362 implicit none
1363 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
1364
1365 integer:: i, move_down
1366 logical:: both_negative, sclsec2_flag_negative
1367 type(dc_scaled_sec):: sclsec1_opsign, sclsec2_opsign
1368 type(dc_scaled_sec):: sclsec1_nosign, sclsec2_nosign
1369 type(dc_scaled_sec):: large, small
1370 continue
1371 both_negative = .false.
1372
1373 ! 負の値の処理
1374 ! Handle negative value
1375 !
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
1380 end if
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.
1386
1387 result = sclsec1_opsign + sclsec2_opsign
1388 if ( both_negative ) then
1389 result % flag_negative = .not. result % flag_negative
1390 end if
1391 return
1392 end if
1393
1394 ! 絶対値の比較
1395 ! Compare absolute values
1396 !
1397 sclsec1_nosign = sclsec1
1398 sclsec1_nosign % flag_negative = .false.
1399 sclsec2_nosign = sclsec2
1400 sclsec2_nosign % flag_negative = .false.
1401
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
1410 else
1411 result = 0
1412 return
1413 end if
1414
1415 move_down = 0
1416 do i = imin, imax
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
1422 else
1423 move_down = 0
1424 end if
1425 end do
1426
1427 if ( both_negative ) then
1428 result % flag_negative = .not. result % flag_negative
1429 end if
1430
1431 end function dcscaledsec_sub_ss
1432
1433 !-------------------------------------------------------------------
1434
1435 !> @en
1436 !> @brief Subtract integer from DC_SCALED_SEC
1437 !> @param[in] sclsec DC_SCALED_SEC variable
1438 !> @param[in] factor Integer value to subtract
1439 !> @return Difference of DC_SCALED_SEC and integer
1440 !> @enden
1441 !>
1442 !> @ja
1443 !> @brief DC_SCALED_SEC から整数を減算
1444 !> @param[in] sclsec DC_SCALED_SEC 型変数
1445 !> @param[in] factor 減算する整数値
1446 !> @return DC_SCALED_SEC と整数の差
1447 !> @endja
1448 type(dc_scaled_sec) function dcscaledsec_sub_si(sclsec, factor) result(result)
1449 implicit none
1450 type(dc_scaled_sec), intent(in):: sclsec
1451 integer, intent(in):: factor
1452 type(dc_scaled_sec):: factor_scl
1453 continue
1454 factor_scl = factor
1455 result = sclsec - factor_scl
1456 end function dcscaledsec_sub_si
1457
1458 !-------------------------------------------------------------------
1459
1460 !> @en
1461 !> @brief Subtract DC_SCALED_SEC from integer
1462 !> @param[in] factor Integer value
1463 !> @param[in] sclsec DC_SCALED_SEC variable to subtract
1464 !> @return Difference of integer and DC_SCALED_SEC
1465 !> @enden
1466 !>
1467 !> @ja
1468 !> @brief 整数から DC_SCALED_SEC を減算
1469 !> @param[in] factor 整数値
1470 !> @param[in] sclsec 減算する DC_SCALED_SEC 型変数
1471 !> @return 整数と DC_SCALED_SEC の差
1472 !> @endja
1473 type(dc_scaled_sec) function dcscaledsec_sub_is(factor, sclsec) result(result)
1474 implicit none
1475 integer, intent(in):: factor
1476 type(dc_scaled_sec), intent(in):: sclsec
1477 type(dc_scaled_sec):: factor_scl
1478 continue
1479 factor_scl = factor
1480 result = factor_scl - sclsec
1481 end function dcscaledsec_sub_is
1482
1483 !-------------------------------------------------------------------
1484
1485 !> @en
1486 !> @brief Subtract real from DC_SCALED_SEC
1487 !> @param[in] sclsec DC_SCALED_SEC variable
1488 !> @param[in] factor Real value to subtract
1489 !> @return Difference of DC_SCALED_SEC and real
1490 !> @enden
1491 !>
1492 !> @ja
1493 !> @brief DC_SCALED_SEC から単精度実数を減算
1494 !> @param[in] sclsec DC_SCALED_SEC 型変数
1495 !> @param[in] factor 減算する実数値
1496 !> @return DC_SCALED_SEC と実数の差
1497 !> @endja
1498 type(dc_scaled_sec) function dcscaledsec_sub_sr(sclsec, factor) result(result)
1499 implicit none
1500 type(dc_scaled_sec), intent(in):: sclsec
1501 real, intent(in):: factor
1502 type(dc_scaled_sec):: factor_scl
1503 continue
1504 factor_scl = factor
1505 result = sclsec - factor_scl
1506 end function dcscaledsec_sub_sr
1507
1508 !-------------------------------------------------------------------
1509
1510 !> @en
1511 !> @brief Subtract DC_SCALED_SEC from real
1512 !> @param[in] factor Real value
1513 !> @param[in] sclsec DC_SCALED_SEC variable to subtract
1514 !> @return Difference of real and DC_SCALED_SEC
1515 !> @enden
1516 !>
1517 !> @ja
1518 !> @brief 単精度実数から DC_SCALED_SEC を減算
1519 !> @param[in] factor 実数値
1520 !> @param[in] sclsec 減算する DC_SCALED_SEC 型変数
1521 !> @return 実数と DC_SCALED_SEC の差
1522 !> @endja
1523 type(dc_scaled_sec) function dcscaledsec_sub_rs(factor, sclsec) result(result)
1524 implicit none
1525 real, intent(in):: factor
1526 type(dc_scaled_sec), intent(in):: sclsec
1527 type(dc_scaled_sec):: factor_scl
1528 continue
1529 factor_scl = factor
1530 result = factor_scl - sclsec
1531 end function dcscaledsec_sub_rs
1532
1533 !-------------------------------------------------------------------
1534
1535 !> @en
1536 !> @brief Subtract double from DC_SCALED_SEC
1537 !> @param[in] sclsec DC_SCALED_SEC variable
1538 !> @param[in] factor Double precision value to subtract
1539 !> @return Difference of DC_SCALED_SEC and double
1540 !> @enden
1541 !>
1542 !> @ja
1543 !> @brief DC_SCALED_SEC から倍精度実数を減算
1544 !> @param[in] sclsec DC_SCALED_SEC 型変数
1545 !> @param[in] factor 減算する倍精度実数値
1546 !> @return DC_SCALED_SEC と倍精度実数の差
1547 !> @endja
1548 type(dc_scaled_sec) function dcscaledsec_sub_sd(sclsec, factor) result(result)
1549 implicit none
1550 type(dc_scaled_sec), intent(in):: sclsec
1551 real(dp), intent(in):: factor
1552 type(dc_scaled_sec):: factor_scl
1553 continue
1554 factor_scl = factor
1555 result = sclsec - factor_scl
1556 end function dcscaledsec_sub_sd
1557
1558 !-------------------------------------------------------------------
1559
1560 !> @en
1561 !> @brief Subtract DC_SCALED_SEC from double
1562 !> @param[in] factor Double precision value
1563 !> @param[in] sclsec DC_SCALED_SEC variable to subtract
1564 !> @return Difference of double and DC_SCALED_SEC
1565 !> @enden
1566 !>
1567 !> @ja
1568 !> @brief 倍精度実数から DC_SCALED_SEC を減算
1569 !> @param[in] factor 倍精度実数値
1570 !> @param[in] sclsec 減算する DC_SCALED_SEC 型変数
1571 !> @return 倍精度実数と DC_SCALED_SEC の差
1572 !> @endja
1573 type(dc_scaled_sec) function dcscaledsec_sub_ds(factor, sclsec) result(result)
1574 implicit none
1575 real(dp), intent(in):: factor
1576 type(dc_scaled_sec), intent(in):: sclsec
1577 type(dc_scaled_sec):: factor_scl
1578 continue
1579 factor_scl = factor
1580 result = factor_scl - sclsec
1581 end function dcscaledsec_sub_ds
1582
1583 !-------------------------------------------------------------------
1584
1585 !> @en
1586 !> @brief Multiply two DC_SCALED_SEC variables
1587 !> @param[in] sclsec1 First DC_SCALED_SEC variable
1588 !> @param[in] sclsec2 Second DC_SCALED_SEC variable
1589 !> @return Product of two DC_SCALED_SEC variables
1590 !> @enden
1591 !>
1592 !> @ja
1593 !> @brief 2つの DC_SCALED_SEC 型変数の乗算
1594 !> @param[in] sclsec1 1番目の DC_SCALED_SEC 型変数
1595 !> @param[in] sclsec2 2番目の DC_SCALED_SEC 型変数
1596 !> @return 2つの DC_SCALED_SEC 型変数の積
1597 !> @endja
1598 type(dc_scaled_sec) function dcscaledsec_mul_ss(sclsec1, sclsec2) result(result)
1599 use dc_message, only: messagenotify
1600 implicit none
1601 type(dc_scaled_sec), intent(in), target:: sclsec1, sclsec2
1602 integer:: sec_ary_int(imin:imax,imin:imax)
1603! real(DP):: sec_ary_int(imin:imax,imin:imax)
1604 integer:: i, j, move_up
1605 type(dc_scaled_sec):: zero_sec
1606 continue
1607 if ( sclsec1 == zero_sec .or. sclsec2 == zero_sec ) then
1608 result = zero_sec
1609 return
1610 end if
1611
1612 if ( sclsec1 % flag_negative ) then
1613 result % flag_negative = .not. sclsec2 % flag_negative
1614 else
1615 result % flag_negative = sclsec2 % flag_negative
1616 end if
1617
1618 move_up = 0
1619 sec_ary_int(:,:) = 0
1620 do i = imin, imax
1621 do j = imin, imax
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
1625 call messagenotify( 'E', 'dc_scaledsec#operator(*)', &
1626 & 'DC_SCALED_SEC must be smaller than 10^24' )
1627 end if
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
1631 else
1632 move_up = 0
1633 end if
1634 end do
1635 end do
1636
1637 result % sec_ary = 0
1638 do i = imin, imax
1639 do j = imin, imax
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)
1643 end do
1644 end do
1645
1646 move_up = 0
1647 do i = imin, imax
1648 result % sec_ary(i) = result % sec_ary(i) + move_up
1649 move_up = 0
1650 do while ( .not. result % sec_ary(i) < scale_factor_int )
1651 if ( i == imax ) then
1652 call messagenotify( 'E', 'dc_scaledsec#operator(*)', &
1653 & 'DC_SCALED_SEC must be smaller than 10^24' )
1654 end if
1655 result % sec_ary(i) = result % sec_ary(i) - scale_factor_int
1656 move_up = move_up + 1
1657 end do
1658 end do
1659
1660 end function dcscaledsec_mul_ss
1661
1662 !-------------------------------------------------------------------
1663
1664 !> @en
1665 !> @brief Multiply DC_SCALED_SEC by integer
1666 !> @details
1667 !> Optimized implementation without using mul_ss for performance.
1668 !> @param[in] sclsec DC_SCALED_SEC variable
1669 !> @param[in] factor Integer multiplier
1670 !> @return Product of DC_SCALED_SEC and integer
1671 !> @enden
1672 !>
1673 !> @ja
1674 !> @brief DC_SCALED_SEC と整数の乗算
1675 !> @details
1676 !> 高速化のため, mul_ss を使用しない最適化実装.
1677 !> @param[in] sclsec DC_SCALED_SEC 型変数
1678 !> @param[in] factor 乗算する整数
1679 !> @return DC_SCALED_SEC と整数の積
1680 !> @endja
1681 type(dc_scaled_sec) function dcscaledsec_mul_si(sclsec, factor) result(result)
1682 use dc_message, only: messagenotify
1683 implicit none
1684 type(dc_scaled_sec), intent(in):: sclsec
1685 integer, intent(in):: factor
1686 integer:: factor_abs
1687 type(dc_scaled_sec):: zero_sec
1688 real(dp):: sec_ary_dp(imin:imax)
1689 integer:: i, move_up
1690 continue
1691 if ( sclsec == zero_sec .or. factor == 0 ) then
1692 result = zero_sec
1693 return
1694 end if
1695
1696 if ( sclsec % flag_negative ) then
1697 result % flag_negative = .not. factor < 0
1698 else
1699 result % flag_negative = factor < 0
1700 end if
1701 factor_abs = abs(factor)
1702
1703 move_up = 0
1704 sec_ary_dp(:) = 0.0_dp
1705 do i = imin, imax
1706 sec_ary_dp(i) = sclsec % sec_ary(i) * factor_abs + move_up
1707
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
1711 else
1712 move_up = 0
1713 end if
1714 end do
1715
1716 if ( move_up /= 0 ) then
1717 call messagenotify( 'E', 'dc_scaledsec#operator(*)', &
1718 & 'DC_SCALED_SEC must be smaller than 10^24' )
1719 end if
1720
1721 result % sec_ary(imin:imax) = nint( sec_ary_dp(imin:imax) )
1722
1723 end function dcscaledsec_mul_si
1724
1725 !-------------------------------------------------------------------
1726
1727 !> @en
1728 !> @brief Multiply integer by DC_SCALED_SEC
1729 !> @param[in] factor Integer multiplier
1730 !> @param[in] sclsec DC_SCALED_SEC variable
1731 !> @return Product of integer and DC_SCALED_SEC
1732 !> @enden
1733 !>
1734 !> @ja
1735 !> @brief 整数と DC_SCALED_SEC の乗算
1736 !> @param[in] factor 乗算する整数
1737 !> @param[in] sclsec DC_SCALED_SEC 型変数
1738 !> @return 整数と DC_SCALED_SEC の積
1739 !> @endja
1740 type(dc_scaled_sec) function dcscaledsec_mul_is(factor, sclsec) result(result)
1741 implicit none
1742 integer, intent(in):: factor
1743 type(dc_scaled_sec), intent(in):: sclsec
1744 continue
1745 result = sclsec * factor
1746 end function dcscaledsec_mul_is
1747
1748 !-------------------------------------------------------------------
1749
1750 !> @en
1751 !> @brief Multiply DC_SCALED_SEC by double precision
1752 !> @param[in] sclsec DC_SCALED_SEC variable
1753 !> @param[in] factor Double precision multiplier
1754 !> @return Product of DC_SCALED_SEC and double
1755 !> @enden
1756 !>
1757 !> @ja
1758 !> @brief DC_SCALED_SEC と倍精度実数の乗算
1759 !> @param[in] sclsec DC_SCALED_SEC 型変数
1760 !> @param[in] factor 乗算する倍精度実数
1761 !> @return DC_SCALED_SEC と倍精度実数の積
1762 !> @endja
1763 type(dc_scaled_sec) function dcscaledsec_mul_sd(sclsec, factor) result(result)
1764 use dc_message, only: messagenotify
1765 implicit none
1766 type(dc_scaled_sec), intent(in):: sclsec
1767 real(dp), intent(in):: factor
1768 type(dc_scaled_sec):: factor_scl
1769 continue
1770 factor_scl = factor
1771 result = sclsec * factor_scl
1772 end function dcscaledsec_mul_sd
1773
1774 !-------------------------------------------------------------------
1775
1776 !> @en
1777 !> @brief Multiply double precision by DC_SCALED_SEC
1778 !> @param[in] factor Double precision multiplier
1779 !> @param[in] sclsec DC_SCALED_SEC variable
1780 !> @return Product of double and DC_SCALED_SEC
1781 !> @enden
1782 !>
1783 !> @ja
1784 !> @brief 倍精度実数と DC_SCALED_SEC の乗算
1785 !> @param[in] factor 乗算する倍精度実数
1786 !> @param[in] sclsec DC_SCALED_SEC 型変数
1787 !> @return 倍精度実数と DC_SCALED_SEC の積
1788 !> @endja
1789 type(dc_scaled_sec) function dcscaledsec_mul_ds(factor, sclsec) result(result)
1790 use dc_message, only: messagenotify
1791 implicit none
1792 real(dp), intent(in):: factor
1793 type(dc_scaled_sec), intent(in):: sclsec
1794 continue
1795 result = sclsec * factor
1796 end function dcscaledsec_mul_ds
1797
1798 !-------------------------------------------------------------------
1799
1800 !> @en
1801 !> @brief Multiply DC_SCALED_SEC by single precision real
1802 !> @param[in] sclsec DC_SCALED_SEC variable
1803 !> @param[in] factor Single precision multiplier
1804 !> @return Product of DC_SCALED_SEC and real
1805 !> @enden
1806 !>
1807 !> @ja
1808 !> @brief DC_SCALED_SEC と単精度実数の乗算
1809 !> @param[in] sclsec DC_SCALED_SEC 型変数
1810 !> @param[in] factor 乗算する単精度実数
1811 !> @return DC_SCALED_SEC と単精度実数の積
1812 !> @endja
1813 type(dc_scaled_sec) function dcscaledsec_mul_sr(sclsec, factor) result(result)
1814 use dc_message, only: messagenotify
1815 implicit none
1816 type(dc_scaled_sec), intent(in):: sclsec
1817 real, intent(in):: factor
1818 type(dc_scaled_sec):: factor_scl
1819 continue
1820 factor_scl = factor
1821 result = sclsec * factor_scl
1822 end function dcscaledsec_mul_sr
1823
1824 !-------------------------------------------------------------------
1825
1826 !> @en
1827 !> @brief Multiply single precision real by DC_SCALED_SEC
1828 !> @param[in] factor Single precision multiplier
1829 !> @param[in] sclsec DC_SCALED_SEC variable
1830 !> @return Product of real and DC_SCALED_SEC
1831 !> @enden
1832 !>
1833 !> @ja
1834 !> @brief 単精度実数と DC_SCALED_SEC の乗算
1835 !> @param[in] factor 乗算する単精度実数
1836 !> @param[in] sclsec DC_SCALED_SEC 型変数
1837 !> @return 単精度実数と DC_SCALED_SEC の積
1838 !> @endja
1839 type(dc_scaled_sec) function dcscaledsec_mul_rs(factor, sclsec) result(result)
1840 use dc_message, only: messagenotify
1841 implicit none
1842 real, intent(in):: factor
1843 type(dc_scaled_sec), intent(in):: sclsec
1844 continue
1845 result = sclsec * factor
1846 end function dcscaledsec_mul_rs
1847
1848 !-------------------------------------------------------------------
1849
1850 !> @en
1851 !> @brief Divide DC_SCALED_SEC by DC_SCALED_SEC
1852 !> @details
1853 !> Note: Due to precision limitations in Fortran compilers,
1854 !> factor must be smaller than 10^12.
1855 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
1856 !> @param[in] factor DC_SCALED_SEC variable (divisor)
1857 !> @return Quotient of division
1858 !> @enden
1859 !>
1860 !> @ja
1861 !> @brief DC_SCALED_SEC を DC_SCALED_SEC で除算
1862 !> @details
1863 !> 注意: Fortran コンパイラの精度制限により,
1864 !> factor は 10^12 未満である必要があります.
1865 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
1866 !> @param[in] factor DC_SCALED_SEC 型変数 (除数)
1867 !> @return 除算の商
1868 !> @endja
1869 type(dc_scaled_sec) function dcscaledsec_div_ss(sclsec, factor) result(result)
1870 use dc_message, only: messagenotify
1871 implicit none
1872 type(dc_scaled_sec), intent(in):: sclsec, factor
1873 real(dp):: factor_abs
1874 continue
1875
1876 ! frt, ifort などでは, 1.0e+23 などの実数とすると,
1877 ! 9.9999e+22 などとなってしまうため,
1878 ! factor として指定するものは 10e+12 までとする.
1879 !
1880 if ( .not. all( factor % sec_ary (imax-4:imax) == (/ 0, 0, 0, 0, 0 /) ) ) then
1881 call messagenotify( 'E', 'dc_scaledsec#mod', &
1882 & 'factor must be smaller than 10^12' )
1883 end if
1884
1885 factor_abs = factor
1886 result = sclsec / factor_abs
1887
1888 end function dcscaledsec_div_ss
1889
1890 !-------------------------------------------------------------------
1891
1892 !> @en
1893 !> @brief Divide DC_SCALED_SEC by integer
1894 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
1895 !> @param[in] factor Integer divisor
1896 !> @return Quotient of division
1897 !> @enden
1898 !>
1899 !> @ja
1900 !> @brief DC_SCALED_SEC を整数で除算
1901 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
1902 !> @param[in] factor 整数の除数
1903 !> @return 除算の商
1904 !> @endja
1905 type(dc_scaled_sec) function dcscaledsec_div_si(sclsec, factor) result(result)
1906 use dc_message, only: messagenotify
1907 implicit none
1908 type(dc_scaled_sec), intent(in):: sclsec
1909 integer, intent(in):: factor
1910 continue
1911 result = sclsec / real( factor, dp )
1912 end function dcscaledsec_div_si
1913
1914 !-------------------------------------------------------------------
1915
1916 !> @en
1917 !> @brief Divide DC_SCALED_SEC by double precision
1918 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
1919 !> @param[in] factor Double precision divisor
1920 !> @return Quotient of division
1921 !> @enden
1922 !>
1923 !> @ja
1924 !> @brief DC_SCALED_SEC を倍精度実数で除算
1925 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
1926 !> @param[in] factor 倍精度実数の除数
1927 !> @return 除算の商
1928 !> @endja
1929 type(dc_scaled_sec) function dcscaledsec_div_sd(sclsec, factor) result(result)
1930 use dc_message, only: messagenotify
1931 use dc_types, only: dp_eps
1932 implicit none
1933 type(dc_scaled_sec), intent(in):: sclsec
1934 real(dp), intent(in):: factor
1935 integer:: i
1936 real(dp):: factor_abs, move_down, sec_ary_mod(imin+imin:imax)
1937 !logical:: flag_approximate
1938 continue
1939 if ( sclsec % flag_negative ) then
1940 result % flag_negative = .not. factor < 0.0_dp
1941 else
1942 result % flag_negative = factor < 0.0_dp
1943 end if
1944 factor_abs = abs(factor) * scale_factor_xx(2)
1945
1946! flag_approximate = .false.
1947 move_down = 0.0_dp
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
1952 else
1953 move_down = 0.0_dp
1954 end if
1955 end do
1956
1957 do i = imax + imin, imin, -1
1958 result % sec_ary(i-imin) = int( ( sclsec % sec_ary(i) + move_down ) / factor_abs )
1959 sec_ary_mod(i) = &
1960 & mod( ( sclsec % sec_ary(i) + move_down ), factor_abs )
1961 if ( abs(sec_ary_mod(i)) > dp_eps ) then
1962 !if ( i < imin ) flag_approximate = .true.
1963 move_down = sec_ary_mod(i) * scale_factor
1964 else
1965 move_down = 0.0_dp
1966 end if
1967 end do
1968
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
1973 !if ( i < imin ) flag_approximate = .true.
1974 move_down = sec_ary_mod(i) * scale_factor
1975 else
1976 move_down = 0.0_dp
1977 end if
1978 end do
1979
1980!!$ if ( flag_approximate ) then
1981!!$ call MessageNotify( 'W', 'dc_scaledsec#operator(/)', &
1982!!$ & 'result may be calculated approximately' )
1983!!$ end if
1984
1985 end function dcscaledsec_div_sd
1986
1987 !-------------------------------------------------------------------
1988
1989 !> @en
1990 !> @brief Divide DC_SCALED_SEC by single precision real
1991 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
1992 !> @param[in] factor Single precision divisor
1993 !> @return Quotient of division
1994 !> @enden
1995 !>
1996 !> @ja
1997 !> @brief DC_SCALED_SEC を単精度実数で除算
1998 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
1999 !> @param[in] factor 単精度実数の除数
2000 !> @return 除算の商
2001 !> @endja
2002 type(dc_scaled_sec) function dcscaledsec_div_sr(sclsec, factor) result(result)
2003 use dc_message, only: messagenotify
2004 implicit none
2005 type(dc_scaled_sec), intent(in):: sclsec
2006 real, intent(in):: factor
2007 continue
2008 result = sclsec / real( factor, dp )
2009 end function dcscaledsec_div_sr
2010
2011 !-------------------------------------------------------------------
2012
2013 !> @en
2014 !> @brief Calculate remainder of DC_SCALED_SEC division
2015 !> @details
2016 !> Note: Due to precision limitations in Fortran compilers,
2017 !> factor must be smaller than 10^12.
2018 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2019 !> @param[in] factor DC_SCALED_SEC variable (divisor)
2020 !> @return Remainder of division
2021 !> @enden
2022 !>
2023 !> @ja
2024 !> @brief DC_SCALED_SEC を割った際の余りを計算
2025 !> @details
2026 !> 注意: Fortran コンパイラの精度制限により,
2027 !> factor は 10^12 未満である必要があります.
2028 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2029 !> @param[in] factor DC_SCALED_SEC 型変数 (除数)
2030 !> @return 除算の余り
2031 !> @endja
2032 type(dc_scaled_sec) function dcscaledsec_mod_ss(sclsec, factor) result(result)
2033 use dc_message, only: messagenotify
2034 use dc_types, only: dp_eps
2035 implicit none
2036 type(dc_scaled_sec), intent(in):: sclsec, factor
2037
2038 type(dc_scaled_sec):: factor_scl
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
2043 type(dc_scaled_sec):: zero_sec
2044 logical:: done
2045 continue
2046
2047 ! factor must be smaller than 10^12 due to compiler precision limitations.
2048 !
2049 if ( .not. all( factor % sec_ary (imax-4:imax) == (/ 0, 0, 0, 0, 0 /) ) ) then
2050 call messagenotify( 'E', 'dc_scaledsec#mod', &
2051 & 'factor must be smaller than 10^12' )
2052 end if
2053
2054 if ( sclsec == factor ) then
2055 result = zero_sec
2056 return
2057 end if
2058
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
2062
2063 factor_dp = factor_scl
2064
2065 done = .false.
2066 move_down = 0.0_dp
2067 do i = imax, imin, -1
2068 move_down_index = i
2069 if ( abs(move_down) > dp_eps ) then
2070 sf_idx = i - imin
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
2074 done = .true.
2075 exit
2076 end if
2077 end if
2078
2079 sec_ary_mod(i) = &
2080 & mod( ( sclsec % sec_ary(i) + move_down ), factor_dp )
2081
2082 if ( abs(sec_ary_mod(i)) > dp_eps ) then
2083 move_down = sec_ary_mod(i) * scale_factor
2084 else
2085 move_down = 0.0_dp
2086 end if
2087 end do
2088
2089 if ( .not. done ) then
2090 do i = imin - 1, imin + imin, -1
2091 move_down_index = i
2092 if ( abs(move_down) > dp_eps ) then
2093 sf_idx = i - imin
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
2097 done = .true.
2098 exit
2099 end if
2100 end if
2101
2102 sec_ary_mod(i) = mod( move_down, factor_dp )
2103
2104 if ( abs(sec_ary_mod(i)) > dp_eps ) then
2105 move_down = sec_ary_mod(i) * scale_factor
2106 else
2107 move_down = 0.0_dp
2108 end if
2109 end do
2110 end if
2111
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)
2115 end if
2116
2117 result % flag_negative = sclsec % flag_negative
2118
2119 end function dcscaledsec_mod_ss
2120
2121 !-------------------------------------------------------------------
2122
2123 !> @en
2124 !> @brief Calculate remainder of DC_SCALED_SEC divided by integer
2125 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2126 !> @param[in] factor Integer divisor
2127 !> @return Remainder of division
2128 !> @enden
2129 !>
2130 !> @ja
2131 !> @brief DC_SCALED_SEC を整数で割った余りを計算
2132 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2133 !> @param[in] factor 整数の除数
2134 !> @return 除算の余り
2135 !> @endja
2136 type(dc_scaled_sec) function dcscaledsec_mod_si(sclsec, factor) result(result)
2137 use dc_message, only: messagenotify
2138 implicit none
2139 type(dc_scaled_sec), intent(in):: sclsec
2140 integer, intent(in):: factor
2141 type(dc_scaled_sec):: factor_scl
2142
2143 continue
2144 factor_scl = factor
2145 result = mod( sclsec, factor_scl )
2146 end function dcscaledsec_mod_si
2147
2148 !-------------------------------------------------------------------
2149
2150 !> @en
2151 !> @brief Calculate remainder of DC_SCALED_SEC divided by real
2152 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2153 !> @param[in] factor Single precision divisor
2154 !> @return Remainder of division
2155 !> @enden
2156 !>
2157 !> @ja
2158 !> @brief DC_SCALED_SEC を単精度実数で割った余りを計算
2159 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2160 !> @param[in] factor 単精度実数の除数
2161 !> @return 除算の余り
2162 !> @endja
2163 type(dc_scaled_sec) function dcscaledsec_mod_sr(sclsec, factor) result(result)
2164 use dc_message, only: messagenotify
2165 implicit none
2166 type(dc_scaled_sec), intent(in):: sclsec
2167 real, intent(in):: factor
2168 type(dc_scaled_sec):: factor_scl
2169
2170 continue
2171 factor_scl = factor
2172 result = mod( sclsec, factor_scl )
2173 end function dcscaledsec_mod_sr
2174
2175 !-------------------------------------------------------------------
2176
2177 !> @en
2178 !> @brief Calculate remainder of DC_SCALED_SEC divided by double
2179 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2180 !> @param[in] factor Double precision divisor
2181 !> @return Remainder of division
2182 !> @enden
2183 !>
2184 !> @ja
2185 !> @brief DC_SCALED_SEC を倍精度実数で割った余りを計算
2186 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2187 !> @param[in] factor 倍精度実数の除数
2188 !> @return 除算の余り
2189 !> @endja
2190 type(dc_scaled_sec) function dcscaledsec_mod_sd(sclsec, factor) result(result)
2191 use dc_message, only: messagenotify
2192 implicit none
2193 type(dc_scaled_sec), intent(in):: sclsec
2194 real(dp), intent(in):: factor
2195 type(dc_scaled_sec):: factor_scl
2196
2197 continue
2198 factor_scl = factor
2199 result = mod( sclsec, factor_scl )
2200 end function dcscaledsec_mod_sd
2201
2202 !-------------------------------------------------------------------
2203
2204 !> @en
2205 !> @brief Calculate modulo of DC_SCALED_SEC division
2206 !> @details
2207 !> Note: Due to precision limitations in Fortran compilers,
2208 !> factor must be smaller than 10^12.
2209 !>
2210 !> The difference from mod: modulo always returns a non-negative result
2211 !> when the divisor is positive (follows Fortran's modulo semantics).
2212 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2213 !> @param[in] factor DC_SCALED_SEC variable (divisor)
2214 !> @return Modulo of division
2215 !> @enden
2216 !>
2217 !> @ja
2218 !> @brief DC_SCALED_SEC を割った際の剰余を計算
2219 !> @details
2220 !> 注意: Fortran コンパイラの精度制限により,
2221 !> factor は 10^12 未満である必要があります.
2222 !>
2223 !> mod との違い: modulo は除数が正の場合、常に非負の結果を返します
2224 !> (Fortran の modulo セマンティクスに従います).
2225 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2226 !> @param[in] factor DC_SCALED_SEC 型変数 (除数)
2227 !> @return 除算の剰余
2228 !> @endja
2229 type(dc_scaled_sec) function dcscaledsec_modulo_ss(sclsec, factor) result(result)
2230 use dc_message, only: messagenotify
2231 use dc_types, only: dp_eps
2232 implicit none
2233 type(dc_scaled_sec), intent(in):: sclsec, factor
2234
2235 type(dc_scaled_sec):: factor_scl
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
2240 type(dc_scaled_sec):: zero_sec
2241 logical:: done
2242 continue
2243
2244 ! factor must be smaller than 10^12 due to compiler precision limitations.
2245 !
2246 if ( .not. all( factor % sec_ary (imax-4:imax) == (/ 0, 0, 0, 0, 0 /) ) ) then
2247 call messagenotify( 'E', 'dc_scaledsec#modulo', &
2248 & 'factor must be smaller than 10^12' )
2249 end if
2250
2251 if ( sclsec == factor ) then
2252 result = zero_sec
2253 return
2254 end if
2255
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
2259
2260 factor_dp = factor_scl
2261
2262 done = .false.
2263 move_down = 0.0_dp
2264 do i = imax, imin, -1
2265 move_down_index = i
2266 if ( abs(move_down) > dp_eps ) then
2267 sf_idx = i - imin
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
2271 done = .true.
2272 exit
2273 end if
2274 end if
2275
2276 sec_ary_mod(i) = &
2277 & mod( ( sclsec % sec_ary(i) + move_down ), factor_dp )
2278
2279 if ( abs(sec_ary_mod(i)) > dp_eps ) then
2280 move_down = sec_ary_mod(i) * scale_factor
2281 else
2282 move_down = 0.0_dp
2283 end if
2284 end do
2285
2286 if ( .not. done ) then
2287 do i = imin - 1, imin + imin, -1
2288 move_down_index = i
2289 if ( abs(move_down) > dp_eps ) then
2290 sf_idx = i - imin
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
2294 done = .true.
2295 exit
2296 end if
2297 end if
2298
2299 sec_ary_mod(i) = mod( move_down, factor_dp )
2300
2301 if ( abs(sec_ary_mod(i)) > dp_eps ) then
2302 move_down = sec_ary_mod(i) * scale_factor
2303 else
2304 move_down = 0.0_dp
2305 end if
2306 end do
2307 end if
2308
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)
2312 end if
2313
2314 result % flag_negative = .false.
2315
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
2320
2321 elseif ( sclsec % flag_negative .and. .not. factor % flag_negative ) then
2322 result = factor - result
2323 result % flag_negative = .not. sclsec % flag_negative
2324
2325 else
2326 result % flag_negative = sclsec % flag_negative
2327
2328 end if
2329 end if
2330
2331 end function dcscaledsec_modulo_ss
2332
2333 !-------------------------------------------------------------------
2334
2335 !> @en
2336 !> @brief Calculate modulo of DC_SCALED_SEC divided by integer
2337 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2338 !> @param[in] factor Integer divisor
2339 !> @return Modulo of division
2340 !> @enden
2341 !>
2342 !> @ja
2343 !> @brief DC_SCALED_SEC を整数で割った剰余を計算
2344 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2345 !> @param[in] factor 整数の除数
2346 !> @return 除算の剰余
2347 !> @endja
2348 type(dc_scaled_sec) function dcscaledsec_modulo_si(sclsec, factor) result(result)
2349 use dc_message, only: messagenotify
2350 implicit none
2351 type(dc_scaled_sec), intent(in):: sclsec
2352 integer, intent(in):: factor
2353 type(dc_scaled_sec):: factor_scl
2354
2355 continue
2356 factor_scl = factor
2357 result = modulo( sclsec, factor_scl )
2358 end function dcscaledsec_modulo_si
2359
2360 !-------------------------------------------------------------------
2361
2362 !> @en
2363 !> @brief Calculate modulo of DC_SCALED_SEC divided by real
2364 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2365 !> @param[in] factor Single precision divisor
2366 !> @return Modulo of division
2367 !> @enden
2368 !>
2369 !> @ja
2370 !> @brief DC_SCALED_SEC を単精度実数で割った剰余を計算
2371 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2372 !> @param[in] factor 単精度実数の除数
2373 !> @return 除算の剰余
2374 !> @endja
2375 type(dc_scaled_sec) function dcscaledsec_modulo_sr(sclsec, factor) result(result)
2376 use dc_message, only: messagenotify
2377 implicit none
2378 type(dc_scaled_sec), intent(in):: sclsec
2379 real, intent(in):: factor
2380 type(dc_scaled_sec):: factor_scl
2381
2382 continue
2383 factor_scl = factor
2384 result = modulo( sclsec, factor_scl )
2385 end function dcscaledsec_modulo_sr
2386
2387 !-------------------------------------------------------------------
2388
2389 !> @en
2390 !> @brief Calculate modulo of DC_SCALED_SEC divided by double
2391 !> @param[in] sclsec DC_SCALED_SEC variable (dividend)
2392 !> @param[in] factor Double precision divisor
2393 !> @return Modulo of division
2394 !> @enden
2395 !>
2396 !> @ja
2397 !> @brief DC_SCALED_SEC を倍精度実数で割った剰余を計算
2398 !> @param[in] sclsec DC_SCALED_SEC 型変数 (被除数)
2399 !> @param[in] factor 倍精度実数の除数
2400 !> @return 除算の剰余
2401 !> @endja
2402 type(dc_scaled_sec) function dcscaledsec_modulo_sd(sclsec, factor) result(result)
2403 use dc_message, only: messagenotify
2404 implicit none
2405 type(dc_scaled_sec), intent(in):: sclsec
2406 real(dp), intent(in):: factor
2407 type(dc_scaled_sec):: factor_scl
2408
2409 continue
2410 factor_scl = factor
2411 result = modulo( sclsec, factor_scl )
2412 end function dcscaledsec_modulo_sd
2413
2414 !-------------------------------------------------------------------
2415
2416 !> @en
2417 !> @brief Return absolute value of DC_SCALED_SEC
2418 !> @param[in] sclsec DC_SCALED_SEC variable
2419 !> @return Absolute value of DC_SCALED_SEC
2420 !> @enden
2421 !>
2422 !> @ja
2423 !> @brief DC_SCALED_SEC の絶対値を返す
2424 !> @param[in] sclsec DC_SCALED_SEC 型変数
2425 !> @return DC_SCALED_SEC の絶対値
2426 !> @endja
2427 type(dc_scaled_sec) function dcscaledsec_abs_s(sclsec) result(result)
2428 implicit none
2429 type(dc_scaled_sec), intent(in):: sclsec
2430
2431 continue
2432 result = sclsec
2433 if ( result % flag_negative ) result % flag_negative = .false.
2434 end function dcscaledsec_abs_s
2435
2436 !-------------------------------------------------------------------
2437
2438 !> @en
2439 !> @brief Return integer part of DC_SCALED_SEC (truncate fractional parts)
2440 !> @param[in] sclsec DC_SCALED_SEC variable
2441 !> @return Integer part of DC_SCALED_SEC (fractional parts truncated)
2442 !> @enden
2443 !>
2444 !> @ja
2445 !> @brief DC_SCALED_SEC の整数部を返す (小数点以下切捨て)
2446 !> @param[in] sclsec DC_SCALED_SEC 型変数
2447 !> @return DC_SCALED_SEC の整数部 (小数点以下切捨て)
2448 !> @endja
2449 type(dc_scaled_sec) function dcscaledsec_int_s(sclsec) result(result)
2450 implicit none
2451 type(dc_scaled_sec), intent(in):: sclsec
2452 integer:: i
2453 continue
2454 result = sclsec
2455 do i = -1, imin, -1
2456 result % sec_ary(i) = 0
2457 end do
2458 end function dcscaledsec_int_s
2459
2460 !-------------------------------------------------------------------
2461
2462 !> @en
2463 !> @brief Return absolute value of sclsec1 with sign of sclsec2
2464 !> @param[in] sclsec1 DC_SCALED_SEC variable (value source)
2465 !> @param[in] sclsec2 DC_SCALED_SEC variable (sign source)
2466 !> @return Absolute value of sclsec1 with sign of sclsec2
2467 !> @enden
2468 !>
2469 !> @ja
2470 !> @brief sclsec1 の絶対値に sclsec2 の符号をつけて返す
2471 !> @param[in] sclsec1 DC_SCALED_SEC 型変数 (値の元)
2472 !> @param[in] sclsec2 DC_SCALED_SEC 型変数 (符号の元)
2473 !> @return sclsec1 の絶対値に sclsec2 の符号をつけたもの
2474 !> @endja
2475 type(dc_scaled_sec) function dcscaledsec_sign_ss(sclsec1, sclsec2) result(result)
2476 implicit none
2477 type(dc_scaled_sec), intent(in):: sclsec1, sclsec2
2478 continue
2479 result = sclsec1
2480 result % flag_negative = sclsec2 % flag_negative
2481 end function dcscaledsec_sign_ss
2482
2483 !-------------------------------------------------------------------
2484
2485 !> @en
2486 !> @brief Return absolute value of sclsec with sign of integer
2487 !> @param[in] sclsec DC_SCALED_SEC variable (value source)
2488 !> @param[in] factor Integer (sign source)
2489 !> @return Absolute value of sclsec with sign of factor
2490 !> @enden
2491 !>
2492 !> @ja
2493 !> @brief sclsec の絶対値に整数の符号をつけて返す
2494 !> @param[in] sclsec DC_SCALED_SEC 型変数 (値の元)
2495 !> @param[in] factor 整数 (符号の元)
2496 !> @return sclsec の絶対値に factor の符号をつけたもの
2497 !> @endja
2498 type(dc_scaled_sec) function dcscaledsec_sign_si(sclsec, factor) result(result)
2499 implicit none
2500 type(dc_scaled_sec), intent(in):: sclsec
2501 integer, intent(in):: factor
2502 type(dc_scaled_sec):: sclsec_work
2503 continue
2504 sclsec_work = factor
2505 result = sign( sclsec, sclsec_work )
2506 end function dcscaledsec_sign_si
2507
2508 !-------------------------------------------------------------------
2509
2510 !> @en
2511 !> @brief Return absolute value of sclsec with sign of real
2512 !> @param[in] sclsec DC_SCALED_SEC variable (value source)
2513 !> @param[in] factor Single precision real (sign source)
2514 !> @return Absolute value of sclsec with sign of factor
2515 !> @enden
2516 !>
2517 !> @ja
2518 !> @brief sclsec の絶対値に単精度実数の符号をつけて返す
2519 !> @param[in] sclsec DC_SCALED_SEC 型変数 (値の元)
2520 !> @param[in] factor 単精度実数 (符号の元)
2521 !> @return sclsec の絶対値に factor の符号をつけたもの
2522 !> @endja
2523 type(dc_scaled_sec) function dcscaledsec_sign_sr(sclsec, factor) result(result)
2524 implicit none
2525 type(dc_scaled_sec), intent(in):: sclsec
2526 real, intent(in):: factor
2527 type(dc_scaled_sec):: sclsec_work
2528 continue
2529 sclsec_work = factor
2530 result = sign( sclsec, sclsec_work )
2531 end function dcscaledsec_sign_sr
2532
2533 !-------------------------------------------------------------------
2534
2535 !> @en
2536 !> @brief Return absolute value of sclsec with sign of double
2537 !> @param[in] sclsec DC_SCALED_SEC variable (value source)
2538 !> @param[in] factor Double precision real (sign source)
2539 !> @return Absolute value of sclsec with sign of factor
2540 !> @enden
2541 !>
2542 !> @ja
2543 !> @brief sclsec の絶対値に倍精度実数の符号をつけて返す
2544 !> @param[in] sclsec DC_SCALED_SEC 型変数 (値の元)
2545 !> @param[in] factor 倍精度実数 (符号の元)
2546 !> @return sclsec の絶対値に factor の符号をつけたもの
2547 !> @endja
2548 type(dc_scaled_sec) function dcscaledsec_sign_sd(sclsec, factor) result(result)
2549 implicit none
2550 type(dc_scaled_sec), intent(in):: sclsec
2551 real(dp), intent(in):: factor
2552 type(dc_scaled_sec):: sclsec_work
2553 continue
2554 sclsec_work = factor
2555 result = sign( sclsec, sclsec_work )
2556 end function dcscaledsec_sign_sd
2557
2558 !-------------------------------------------------------------------
2559
2560 !> @en
2561 !> @brief Return floor of DC_SCALED_SEC (maximum integer not greater than value)
2562 !> @param[in] sclsec DC_SCALED_SEC variable
2563 !> @return Maximum integer not greater than sclsec
2564 !> @enden
2565 !>
2566 !> @ja
2567 !> @brief DC_SCALED_SEC の床関数を返す (対象の数値以下で最大の整数)
2568 !> @param[in] sclsec DC_SCALED_SEC 型変数
2569 !> @return sclsec 以下で最大の整数
2570 !> @endja
2571 type(dc_scaled_sec) function dcscaledsec_floor_s(sclsec) result(result)
2572 implicit none
2573 type(dc_scaled_sec), intent(in):: sclsec
2574 integer:: i
2575 logical:: flag_after_decimal
2576 continue
2577 result = sclsec
2578 flag_after_decimal = .false.
2579 do i = -1, imin, -1
2580 if ( result % sec_ary(i) /= 0 ) flag_after_decimal = .true.
2581 result % sec_ary(i) = 0
2582 end do
2583 if ( flag_after_decimal .and. result % flag_negative ) then
2584 result = result - 1
2585 end if
2586
2587 end function dcscaledsec_floor_s
2588
2589 !-------------------------------------------------------------------
2590
2591 !> @en
2592 !> @brief Return ceiling of DC_SCALED_SEC (minimum integer not less than value)
2593 !> @param[in] sclsec DC_SCALED_SEC variable
2594 !> @return Minimum integer not less than sclsec
2595 !> @enden
2596 !>
2597 !> @ja
2598 !> @brief DC_SCALED_SEC の天井関数を返す (対象の数値以上で最小の整数)
2599 !> @param[in] sclsec DC_SCALED_SEC 型変数
2600 !> @return sclsec 以上で最小の整数
2601 !> @endja
2602 type(dc_scaled_sec) function dcscaledsec_ceiling_s(sclsec) result(result)
2603 implicit none
2604 type(dc_scaled_sec), intent(in):: sclsec
2605 integer:: i
2606 logical:: flag_after_decimal
2607 continue
2608 result = sclsec
2609 flag_after_decimal = .false.
2610 do i = -1, imin, -1
2611 if ( result % sec_ary(i) /= 0 ) flag_after_decimal = .true.
2612 result % sec_ary(i) = 0
2613 end do
2614 if ( flag_after_decimal .and. .not. result % flag_negative ) then
2615 result = result + 1
2616 end if
2617
2618 end function dcscaledsec_ceiling_s
2619
2620 !-------------------------------------------------------------------
2621 !----------------- 内部サブルーチン ------------------------------
2622 ! Internal subroutines
2623 !-------------------------------------------------------------------
2624
2625 !> @en
2626 !> @brief Count number of digits in an integer
2627 !> @details
2628 !> Internal function used for determining precision.
2629 !> @param[in] sec Integer value to count digits
2630 !> @return Number of digits
2631 !> @enden
2632 !>
2633 !> @ja
2634 !> @brief 整数の桁数をカウント
2635 !> @details
2636 !> 精度判定に使用する内部関数.
2637 !> @param[in] sec 桁数をカウントする整数値
2638 !> @return 桁数
2639 !> @endja
2640 function count_digit(sec) result(result)
2641 implicit none
2642 integer, intent(in):: sec
2643 integer:: result
2644
2645 integer:: i
2646 continue
2647
2648 do i = 5, 0, -1
2649 if ( .not. sec < 10**i ) then
2650 result = i+1
2651 return
2652 end if
2653 end do
2654 result = 0
2655
2656 end function count_digit
2657
2658 !> @namespace dc_scaledsec
2659end module dc_scaledsec
Error handling module.
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public dc_noerr
Error storage variables
Definition dc_error.f90:468
integer, parameter, public dc_etoolargetime
Definition dc_error.f90:551
Message output module.
Scaled seconds module for precise time operations.
subroutine, public dcscaledsecputline(sclsec, unit, indent)
Handling character types.
Definition dc_string.f90:83
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:476
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:599
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
real(dp), parameter, public dp_eps
Machine epsilon for dobule precision real number.
Definition dc_types.f90:97
integer, parameter, public stdout
Unit number for Standard OUTPUT
Definition dc_types.f90:117
integer, parameter, public dp
Double Precision Real number
Definition dc_types.f90:92