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!-----------------------------------------------------------------------
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
129 sequence
130 integer:: sec_ary(imin:imax) = 0
131 logical:: flag_negative = .false.
132 logical:: dummy = .false.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 stdout
Unit number for Standard OUTPUT
Definition dc_types.f90:117
integer, parameter, public dp
Double Precision Real number
Definition dc_types.f90:92
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