PrecisionModel.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import HashMap from '../../../../java/util/HashMap'
  2. import Coordinate from './Coordinate'
  3. import Double from '../../../../java/lang/Double'
  4. import Integer from '../../../../java/lang/Integer'
  5. import Comparable from '../../../../java/lang/Comparable'
  6. import Serializable from '../../../../java/io/Serializable'
  7. export default class PrecisionModel {
  8. constructor() {
  9. PrecisionModel.constructor_.apply(this, arguments)
  10. }
  11. static constructor_() {
  12. this._modelType = null
  13. this._scale = null
  14. if (arguments.length === 0)
  15. this._modelType = PrecisionModel.FLOATING
  16. else if (arguments.length === 1)
  17. if (arguments[0] instanceof Type) {
  18. const modelType = arguments[0]
  19. this._modelType = modelType
  20. if (modelType === PrecisionModel.FIXED)
  21. this.setScale(1.0)
  22. } else if (typeof arguments[0] === 'number') {
  23. const scale = arguments[0]
  24. this._modelType = PrecisionModel.FIXED
  25. this.setScale(scale)
  26. } else if (arguments[0] instanceof PrecisionModel) {
  27. const pm = arguments[0]
  28. this._modelType = pm._modelType
  29. this._scale = pm._scale
  30. }
  31. }
  32. static mostPrecise(pm1, pm2) {
  33. if (pm1.compareTo(pm2) >= 0) return pm1
  34. return pm2
  35. }
  36. equals(other) {
  37. if (!(other instanceof PrecisionModel))
  38. return false
  39. const otherPrecisionModel = other
  40. return this._modelType === otherPrecisionModel._modelType && this._scale === otherPrecisionModel._scale
  41. }
  42. compareTo(o) {
  43. const other = o
  44. const sigDigits = this.getMaximumSignificantDigits()
  45. const otherSigDigits = other.getMaximumSignificantDigits()
  46. return Integer.compare(sigDigits, otherSigDigits)
  47. }
  48. getScale() {
  49. return this._scale
  50. }
  51. isFloating() {
  52. return this._modelType === PrecisionModel.FLOATING || this._modelType === PrecisionModel.FLOATING_SINGLE
  53. }
  54. getType() {
  55. return this._modelType
  56. }
  57. toString() {
  58. let description = 'UNKNOWN'
  59. if (this._modelType === PrecisionModel.FLOATING)
  60. description = 'Floating'
  61. else if (this._modelType === PrecisionModel.FLOATING_SINGLE)
  62. description = 'Floating-Single'
  63. else if (this._modelType === PrecisionModel.FIXED)
  64. description = 'Fixed (Scale=' + this.getScale() + ')'
  65. return description
  66. }
  67. makePrecise() {
  68. if (typeof arguments[0] === 'number') {
  69. const val = arguments[0]
  70. if (Double.isNaN(val)) return val
  71. if (this._modelType === PrecisionModel.FLOATING_SINGLE) {
  72. const floatSingleVal = val
  73. return floatSingleVal
  74. }
  75. if (this._modelType === PrecisionModel.FIXED)
  76. return Math.round(val * this._scale) / this._scale
  77. return val
  78. } else if (arguments[0] instanceof Coordinate) {
  79. const coord = arguments[0]
  80. if (this._modelType === PrecisionModel.FLOATING) return null
  81. coord.x = this.makePrecise(coord.x)
  82. coord.y = this.makePrecise(coord.y)
  83. }
  84. }
  85. getMaximumSignificantDigits() {
  86. let maxSigDigits = 16
  87. if (this._modelType === PrecisionModel.FLOATING)
  88. maxSigDigits = 16
  89. else if (this._modelType === PrecisionModel.FLOATING_SINGLE)
  90. maxSigDigits = 6
  91. else if (this._modelType === PrecisionModel.FIXED)
  92. maxSigDigits = 1 + Math.trunc(Math.ceil(Math.log(this.getScale()) / Math.log(10)))
  93. return maxSigDigits
  94. }
  95. setScale(scale) {
  96. this._scale = Math.abs(scale)
  97. }
  98. get interfaces_() {
  99. return [Serializable, Comparable]
  100. }
  101. }
  102. class Type {
  103. constructor() {
  104. Type.constructor_.apply(this, arguments)
  105. }
  106. static constructor_() {
  107. this._name = null
  108. const name = arguments[0]
  109. this._name = name
  110. Type.nameToTypeMap.put(name, this)
  111. }
  112. readResolve() {
  113. return Type.nameToTypeMap.get(this._name)
  114. }
  115. toString() {
  116. return this._name
  117. }
  118. get interfaces_() {
  119. return [Serializable]
  120. }
  121. }
  122. Type.nameToTypeMap = new HashMap()
  123. PrecisionModel.Type = Type
  124. PrecisionModel.FIXED = new Type('FIXED')
  125. PrecisionModel.FLOATING = new Type('FLOATING')
  126. PrecisionModel.FLOATING_SINGLE = new Type('FLOATING SINGLE')
  127. PrecisionModel.maximumPreciseValue = 9007199254740992.0