Changeset 365
- Timestamp:
- Oct 27, 2007, 12:58:11 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Include/Classes/ActiveBasic/Strings/SPrintF.ab
r364 r365 39 39 x = -x 40 40 Else 41 42 41 sign = False 43 42 End If … … 65 64 e = d 66 65 67 FloatToChars = Str$(x As QWord)66 FloatToChars = FormatIntegerLU((x As Int64) As QWord, 17, 0, None) 68 67 End Function 69 68 … … 102 101 '! 大文字。使用するアルファベットを大文字にする。[aefgx]を[AEFGX]化する。 103 102 Cap = &h20 103 104 /*! 105 内部処理用に予約。 106 @note Minusとして使用されている。 107 */ 108 Reserved = &h80000000 104 109 End Enum 105 110 … … 108 113 @author Egtra 109 114 @date 2007/09/18 110 @param[in] 111 @param[in] 112 @param[in] 113 @param[in] 114 @return 115 116 @todo 115 @param[in] x 文字列化する浮動小数点数値。 116 @param[in] d 精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値6となる。 117 @param[in] field フィールド幅。 118 @param[in] flags 書式フラグ。 119 @return xの文字列表現 120 121 @todo 他の実装での末尾桁の扱いを調べる(このコードでは何もしていないので切捨となっている)。 117 122 */ 118 123 Function FormatFloatE(x As Double, d As DWord, field As DWord, flags As FormatFlags) As String … … 156 161 157 162 /*! 158 @brief 浮動小数点数をprintfの%f(小数 点数形式、十進法)相当の変換で文字列化する関数。163 @brief 浮動小数点数をprintfの%f(小数形式、十進法)相当の変換で文字列化する関数。 159 164 @author Egtra 160 165 @date 2007/10/23 … … 238 243 End Sub 239 244 240 '! DWordの最大値4294967295の文字数 - 1。FormatIntegerU内で使用。 245 /*! 246 @brief DWordの最大値4294967295の文字数 - 1。FormatIntegerU内で使用。 247 @author Egtra 248 @date 2007/09/18 249 */ 241 250 Const MaxSizeU = 9 242 251 … … 252 261 */ 253 262 Function FormatIntegerU(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String 254 FormatIntegerU = FormatInteger(x, d, field, flags And (Not (Sign Or Blank)), 0) 255 End Function 256 257 /*! 258 DWordの最大値4294967295やLongの最大値2147483647、最小値-2147483648 259 (全て十進法)の符号部を除いた文字数 - 1。FormatIntegerU内で使用。 260 */ 261 Const MaxSizeD = 9 263 Return FormatIntegerEx(TraitsIntegerDU, x, d, field, flags And (Not (Sign Or Blank))) 264 End Function 265 266 /*! 267 @brief FormatIntegerUのQWord版 268 @author Egtra 269 @date 2007/10/26 270 */ 271 Function FormatIntegerLU(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String 272 Return FormatIntegerEx(TraitsIntegerLDU, x, d, field, flags And (Not (Sign Or Blank))) 273 End Function 262 274 263 275 /*! … … 272 284 */ 273 285 Function FormatIntegerD(x As Long, d As DWord, field As DWord, flags As FormatFlags) As String 274 Dim dwX As DWord 275 276 Dim signChar As StrChar 286 Dim unsignedX As DWord 277 287 If x < 0 Then 278 dwX = (-x) As DWord 279 signChar = Asc("-") 280 flags Or= Sign 288 unsignedX = (-x) As DWord 289 flags Or= Minus 281 290 Else 282 dwX = x As DWord 283 If flags And Sign Then 284 signChar = Asc("+") 285 ElseIf flags And Blank Then 286 signChar = Asc(" ") 287 End If 288 End If 289 290 FormatIntegerD = FormatInteger(dwX, d, field, flags, signChar) 291 End Function 292 293 /*! 294 @brief 整数をprintfの%d, %u相当の変換で文字列化する関数。 295 @author Egtra 296 @date 2007/09/18 297 @param[in] x 文字列化する整数値。 298 @param[in] d 精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。 299 @param[in] field フィールド幅。 300 @param[in] flags 書式フラグ。 301 @param[in] signChar 符号部分の文字。\0なら存在しないとして扱われる。 302 @return xの文字列表現 303 304 signCharに何らかの値を指定するときには、必ずflagsにSignまたはBlankを指定すること。 305 さもないと、フィールド幅を指定したときに正しく整形されなくなる。 306 */ 307 Function FormatInteger(x As DWord, d As DWord, field As DWord, flags As FormatFlags, signChar As StrChar) As String 308 PreProcessFormatInteger(d, flags) 309 310 Dim sb = New System.Text.StringBuilder 311 With sb 312 If signChar <> 0 Then 313 .Append(signChar) 314 End If 315 316 Dim buf[MaxSizeU] As StrChar 317 Dim i = MaxSizeU 318 While x <> 0 319 buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策 320 x \= 10 321 i-- 322 Wend 323 324 Dim len = (MaxSizeU - i) As Long 325 If len < d Then 326 .Append(&h30 As StrChar, d - len) 327 End If 328 329 .Append(buf, i + 1, len) 330 331 AdjustFieldWidth(sb, field, flags) 332 End With 333 FormatInteger = sb.ToString() 334 End Function 335 336 /*! 337 DWordの最大値の八進法表現37777777777の文字数 - 1 + 1。FormatIntegerO内で使用。 291 unsignedX = x As DWord 292 End If 293 294 Return FormatIntegerEx(TraitsIntegerDU, unsignedX, d, field, flags) 295 End Function 296 297 /*! 298 @brief FormatIntegerDのInt64版 299 @author Egtra 300 @date 2007/10/26 301 */ 302 Function FormatIntegerLD(x As Int64, d As DWord, field As DWord, flags As FormatFlags) As String 303 Dim unsignedX As QWord 304 If x < 0 Then 305 unsignedX = (-x) As QWord 306 flags Or= Minus 307 Else 308 unsignedX = x As QWord 309 End If 310 311 Return FormatIntegerEx(TraitsIntegerLDU, unsignedX, d, field, flags) 312 End Function 313 314 /*! 315 @author Egtra 316 @date 2007/10/26 317 */ 318 Dim TraitsIntegerDU As IntegerConvertTraits 319 With TraitsIntegerDU 320 .Convert = AddressOf(IntegerDU_Convert) 321 .Prefix = AddressOf(IntegerDU_Prefix) 322 .MaxSize = MaxSizeU 323 End With 324 325 /*! 326 @author Egtra 327 @date 2007/10/26 328 */ 329 Dim TraitsIntegerLDU As IntegerConvertTraits 330 With TraitsIntegerLDU 331 .Convert = AddressOf(IntegerLDU_Convert) 332 .Prefix = AddressOf(IntegerDU_Prefix) 333 .MaxSize = MaxSizeLU 334 End With 335 336 /*! 337 @brief 負数を表すフラグ。FormatIntegerD, LDからIntegerDU_Prefixまでの内部処理用。 338 @author Egtra 339 @date 2007/10/26 340 */ 341 Const Minus = Reserved 342 343 /*! 344 @author Egtra 345 @date 2007/10/26 346 */ 347 Function IntegerDU_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord 348 Dim x = xq As DWord 349 Dim i = MaxSizeU 350 While x <> 0 351 buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策 352 x \= 10 353 i-- 354 Wend 355 Return i 356 End Function 357 358 /*! 359 @brief IntegerDU_ConvertのQWord版 360 @author Egtra 361 @date 2007/10/26 362 @bug #117のため、現在Int64の最大値を超える値を正しく処理できない。 363 */ 364 Function IntegerLDU_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord 365 Dim i = MaxSizeLU 366 While x <> 0 367 buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策 368 x \= 10 369 i-- 370 Wend 371 Return i 372 End Function 373 374 /*! 375 @author Egtra 376 @date 2007/10/26 377 */ 378 Function IntegerDU_Prefix(x As QWord, flags As FormatFlags) As String 379 If flags And Minus Then 380 IntegerDU_Prefix = "-" 381 ElseIf flags And Sign Then 382 IntegerDU_Prefix = "+" 383 ElseIf flags And Blank Then 384 IntegerDU_Prefix = " " 385 End If 386 End Function 387 388 /*! 389 @brief DWordの最大値の八進法表現37777777777の文字数 - 1 + 1。IntegerO_Convert内で使用。 390 @author Egtra 391 @date 2007/10/19 338 392 上の式で1を加えているのは、八進接頭辞の分。 339 393 */ 340 394 Const MaxSizeO = 11 341 395 396 /*! 397 @brief QWordの最大値の八進法表現1777777777777777777777の文字数 - 1 + 1。IntegerO_Convert内で使用。 398 @author Egtra 399 @date 2007/10/26 400 上の式で1を加えているのは、八進接頭辞の分。 401 */ 402 Const MaxSizeLO = 22 403 404 /*! 405 @author Egtra 406 @date 2007/10/22 407 */ 342 408 Dim TraitsIntegerO As IntegerConvertTraits 343 409 With TraitsIntegerO … … 348 414 349 415 /*! 416 @author Egtra 417 @date 2007/10/26 418 */ 419 Dim TraitsIntegerLO As IntegerConvertTraits 420 With TraitsIntegerLO 421 .Convert = AddressOf(IntegerLO_Convert) 422 .Prefix = AddressOf(IntegerO_Prefix) 423 .MaxSize = MaxSizeLO 424 End With 425 426 /*! 350 427 @brief 符号無し整数をprintfの%o(八進法表現)相当の変換で文字列化する関数。 351 428 @author Egtra … … 358 435 */ 359 436 Function FormatIntegerO(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String 360 FormatIntegerO = FormatIntegerEx(TraitsIntegerO, x, d, field, flags) 361 End Function 362 437 Return FormatIntegerEx(TraitsIntegerO, x, d, field, flags) 438 End Function 439 440 /*! 441 @brief FormatIntegerOのQWord版。 442 @author Egtra 443 @date 2007/10/26 444 */ 445 Function FormatIntegerLO(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String 446 Return FormatIntegerEx(TraitsIntegerLO, x, d, field, flags) 447 End Function 448 449 /*! 450 @author Egtra 451 @date 2007/10/22 452 */ 363 453 Function IntegerO_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord 364 454 Dim x = xq As DWord … … 373 463 i-- 374 464 End If 375 IntegerO_Convert = i 376 End Function 377 465 Return i 466 End Function 467 468 /*! 469 @brief IntegerO_ConvertのQWord版。 470 @author Egtra 471 @date 2007/10/26 472 */ 473 Function IntegerLO_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord 474 Dim i = MaxSizeLO 475 While x <> 0 476 buf[i] = ((x And &o7) + &h30) As StrChar 477 x >>= 3 478 i-- 479 Wend 480 If flags And Alt Then 481 buf[i] = &h30 482 i-- 483 End If 484 Return i 485 End Function 486 487 /*! 488 @author Egtra 489 @date 2007/10/22 490 @note #フラグ (Alt)の処理は、IntegerO/LO_Convert内で行うので、ここで処理することはない。 491 */ 378 492 Function IntegerO_Prefix(x As QWord, flags As FormatFlags) As String 379 493 End Function 380 494 381 495 /*! 382 DWordの最大値の十六進法表現ffffffffの文字数 - 1。FormatIntegerO内で使用。 496 @brief DWordの最大値の十六進法表現ffffffffの文字数 - 1。FormatIntegerO内で使用。 497 @author Egtra 498 @date 2007/10/24 383 499 */ 384 500 Const MaxSizeX = 7 385 501 502 /*! 503 @brief QWordの最大値の十六進法表現ffffffffffffffffの文字数 - 1。FormatIntegerO内で使用。 504 @author Egtra 505 @date 2007/10/26 506 */ 507 Const MaxSizeLX = 15 508 509 /*! 510 @author Egtra 511 @date 2007/10/24 512 */ 386 513 Dim TraitsIntegerX As IntegerConvertTraits 387 514 With TraitsIntegerX … … 392 519 393 520 /*! 521 @author Egtra 522 @date 2007/10/26 523 */ 524 Dim TraitsIntegerLX As IntegerConvertTraits 525 With TraitsIntegerLX 526 .Convert = AddressOf(IntegerLX_Convert) 527 .Prefix = AddressOf(IntegerX_Prefix) 528 .MaxSize = MaxSizeLX 529 End With 530 531 /*! 394 532 @brief 整数をprintfの%x, %X(十六進法)相当の変換で文字列化する関数。 395 533 @author Egtra … … 402 540 */ 403 541 Function FormatIntegerX(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String 404 FormatIntegerX = FormatIntegerEx(TraitsIntegerX, x, d, field, flags) 405 End Function 406 542 Return FormatIntegerEx(TraitsIntegerX, x, d, field, flags) 543 End Function 544 545 /*! 546 @brief FormatIntegerXのQWord版。 547 @author Egtra 548 @date 2007/10/22 549 */ 550 Function FormatIntegerLX(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String 551 Return FormatIntegerEx(TraitsIntegerLX, x, d, field, flags) 552 End Function 553 554 /*! 555 @author Egtra 556 @date 2007/10/22 557 */ 407 558 Function IntegerX_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord 408 559 Dim i = MaxSizeX … … 413 564 i-- 414 565 Wend 415 IntegerX_Convert = i 416 End Function 417 566 Return i 567 End Function 568 569 /*! 570 @brief IntegerX_ConvertのQWord版。 571 @author Egtra 572 @date 2007/10/22 573 */ 574 Function IntegerLX_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord 575 Dim i = MaxSizeLX 576 While x <> 0 577 buf[i] = _System_HexadecimalTable[x And &h0f] 578 x >>= 4 579 i-- 580 Wend 581 Return i 582 End Function 583 584 /*! 585 @author Egtra 586 @date 2007/10/24 587 */ 418 588 Function IntegerX_Prefix(x As QWord, flags As FormatFlags) As String 419 589 If flags And Alt Then … … 424 594 End Function 425 595 596 /*! 597 @brief FormatIntegerExへ渡す変換特性を表す構造体型。 598 @author Egtra 599 @date 2007/10/22 600 */ 426 601 Type IntegerConvertTraits 602 '!変換を行う関数へのポインタ。 427 603 Convert As *Function(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord 604 '!接頭辞を取得する関数へのポインタ。 428 605 Prefix As *Function(x As QWord, flags As FormatFlags) As String 606 '!必要なバッファの大きさ。 429 607 MaxSize As DWord 430 608 End Type … … 441 619 */ 442 620 Function FormatIntegerEx(ByRef tr As IntegerConvertTraits, x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String 443 PreProcessFormatInteger(d, flags) 621 If d = DWORD_MAX Then 622 d = 1 623 Else 624 '精度が指定されているとき、ゼロフラグは無視される。 625 '仕様上、左揃えのときも無視されるが、それはAdjustFieldWidthが行ってくれる。 626 flags And= Not Zero 627 End If 444 628 445 629 Dim sb = New System.Text.StringBuilder … … 459 643 460 644 Dim len = (tr.MaxSize - bufStartPos) As Long 645 If len < 0 Then 646 Debug 647 End If 461 648 If len < d Then 462 649 .Append(&h30 As StrChar, d - len) … … 474 661 End Function 475 662 476 '! QWordの最大値18446744073709551615の文字数 - 1。FormatIntegerLU内で使用。 663 /*! 664 @brief QWordの最大値18446744073709551615の文字数 - 1。FormatIntegerLU内で使用。 665 @author Egtra 666 @date 2007/09/18 667 */ 477 668 Const MaxSizeLU = 19 478 669 479 670 /*! 480 @brief 整数変換共通の前処理 481 @author Egtra 482 @date 2007/10/19 483 @param[in, out] d 精度。DWORD_MAXで省略とみなされ、精度1になる。 484 @param[in, out] flags フラグ。精度が指定されたとき、Zeroを消す。 485 */ 486 Sub PreProcessFormatInteger(ByRef d As DWord, ByRef flags As FormatFlags) 487 If d = DWORD_MAX Then 488 d = 1 489 Else 490 '精度が指定されているとき、ゼロフラグは無視される。 491 '仕様上、左揃えのときも無視されるが、それはAdjustFieldWidthが行ってくれる。 492 flags And= Not Zero 493 End If 494 End Sub 495 496 /*! 497 @brief 文字列をフィールド幅まで満たされるように空白などを挿入する。 498 @param [in,out] sb 対象文字列 499 @param [in] field フィールド幅 500 @param [in] hasSign 符号を持っている(負の値か)か否か 501 @param [in] flags フラグ 502 @param [in] prefixLen (あれば)接頭辞の文字数。ゼロ埋めする際、この数だけ挿入位置を後ろにする。 671 @brief 文字列をフィールド幅まで満たされるように空白などを挿入する。 672 @author Egtra 673 @date 2007/10/13 674 @param[in,out] sb 対象文字列 675 @param[in] field フィールド幅 676 @param[in] hasSign 符号を持っている(負の値か)か否か 677 @param[in] flags フラグ 678 @param[in] prefixLen (あれば)接頭辞の文字数。ゼロ埋めする際、この数だけ挿入位置を後ろにする。 503 679 sbが"-1"のように負符号を持っている場合は、呼出元でSignフラグ(またはBlank)を立てること。 504 680 */ -
trunk/TestCase/SimpleTestCase/SPrintFTest.ab
r364 r365 96 96 UnitTest("FormatFloatF(1.00, precision = 2)", Right$(s, 6) = "000.00") 97 97 98 ' s = FormatIntegerLU(8589934590, DWORD_MAX, 0, None) 99 ' UnitTest("FormatIntegerLU(8589934590)", s = "8589934590") 98 s = FormatIntegerLO(&hFFFFFFFFFFFFFFFF, 0, 0, Alt) 99 UnitTest("FormatIntegerLO(&hFFFFFFFFFFFFFFFF, Alt) = 01777777777777777777777", s = "01777777777777777777777") 100 s = FormatIntegerLX(&h123456789abcdef0, 0, 0, None) 101 UnitTest("FormatIntegerLX(&h123456789abcdef0)", s = "123456789abcdef0") 102 s = FormatIntegerLU(8589934590 As QWord, DWORD_MAX, 0, None) 103 UnitTest("FormatIntegerLU(8589934590)", s = "8589934590") 104 s = FormatIntegerLD(-8589934590, DWORD_MAX, 0, None) 105 UnitTest("FormatIntegerLD(-8589934590)", s = "-8589934590") 100 106 End Sub 101 107
Note:
See TracChangeset
for help on using the changeset viewer.