На самом деле все зависит от того, для чего вам нужна случайная генерация, но вот мое занятие.
Сначала создайте автономный метод для генерации случайного числа. Обязательно допустим ограничения.
public static int newRandom(int limit){
return generatedRandom.nextInt(limit); }
Затем вам нужно создать очень простую структуру принятия решений, которая сравнивает значения. Это можно сделать одним из двух способов. Если у вас есть очень ограниченное количество чисел для проверки, достаточно простого оператора IF:
public static int testDuplicates(int int1, int int2, int int3, int int4, int int5){
boolean loopFlag = true;
while(loopFlag == true){
if(int1 == int2 || int1 == int3 || int1 == int4 || int1 == int5 || int1 == 0){
int1 = newRandom(75);
loopFlag = true; }
else{
loopFlag = false; }}
return int1; }
Вышеприведенное сравнивает int1 с int2 через int5, а также гарантирует отсутствие нулей в randoms.
Используя эти два метода, мы можем сделать следующее:
num1 = newRandom(limit1);
num2 = newRandom(limit1);
num3 = newRandom(limit1);
num4 = newRandom(limit1);
num5 = newRandom(limit1);
Followed:
num1 = testDuplicates(num1, num2, num3, num4, num5);
num2 = testDuplicates(num2, num1, num3, num4, num5);
num3 = testDuplicates(num3, num1, num2, num4, num5);
num4 = testDuplicates(num4, num1, num2, num3, num5);
num5 = testDuplicates(num5, num1, num2, num3, num5);
Если у вас есть более длинный список для проверки, то более сложный метод даст лучшие результаты как в ясности кода, так и в обработке ресурсов.
Надеюсь, это поможет. Этот сайт мне очень помог, я чувствовал себя обязанным, по крайней мере, ПОПРОБОВАТЬ, чтобы помочь.
Вы можете использовать scala.math.BigDecimal
:
BigDecimal(1.23456789).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
Существует ряд других режимов округления , которые, к сожалению, не очень хорошо (хотя их эквиваленты Java являются ).
Так как никто еще не упомянул оператор %
, то здесь. Он только усекает, и вы не можете полагаться на возвращаемое значение, чтобы не иметь неточностей с плавающей запятой, но иногда это удобно:
scala> 1.23456789 - (1.23456789 % 0.01)
res4: Double = 1.23
26.257391515826225 - 0.057391515826223094 = 26.200000000000003
– kubudi
9 July 2015 в 14:37
Как насчет:
val value = 1.4142135623730951
//3 decimal places
println((value * 1000).round / 1000.toDouble)
//4 decimal places
println((value * 10000).round / 10000.toDouble)
((1.949 * 1000).toInt - ((1.949 * 1000).toInt % 10)) / 1000.toDouble
не испытывал его слишком много, хотя. Этот код будет делать 2 десятичных знака.
– robert
30 March 2016 в 07:45
Для тех, кому интересно, вот несколько раз для предлагаемых решений ...
Rounding
Java Formatter: Elapsed Time: 105
Scala Formatter: Elapsed Time: 167
BigDecimal Formatter: Elapsed Time: 27
Truncation
Scala custom Formatter: Elapsed Time: 3
Усечение является самым быстрым, за которым следует BigDecimal. Имейте в виду, что эти тесты были выполнены с использованием нормального исполнения scala, а не с использованием инструментов бенчмаркинга.
object TestFormatters {
val r = scala.util.Random
def textFormatter(x: Double) = new java.text.DecimalFormat("0.##").format(x)
def scalaFormatter(x: Double) = "$pi%1.2f".format(x)
def bigDecimalFormatter(x: Double) = BigDecimal(x).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
def scalaCustom(x: Double) = {
val roundBy = 2
val w = math.pow(10, roundBy)
(x * w).toLong.toDouble / w
}
def timed(f: => Unit) = {
val start = System.currentTimeMillis()
f
val end = System.currentTimeMillis()
println("Elapsed Time: " + (end - start))
}
def main(args: Array[String]): Unit = {
print("Java Formatter: ")
val iters = 10000
timed {
(0 until iters) foreach { _ =>
textFormatter(r.nextDouble())
}
}
print("Scala Formatter: ")
timed {
(0 until iters) foreach { _ =>
scalaFormatter(r.nextDouble())
}
}
print("BigDecimal Formatter: ")
timed {
(0 until iters) foreach { _ =>
bigDecimalFormatter(r.nextDouble())
}
}
print("Scala custom Formatter (truncation): ")
timed {
(0 until iters) foreach { _ =>
scalaCustom(r.nextDouble())
}
}
}
}
...truncate or round a Double
.
– cevaris
8 January 2018 в 19:19
doubleParts.tail
и concat со строками ». & quot; и doubleParts. head
и разобрать вдвое.
– Ravinder Payal
9 January 2018 в 04:56
toString.split(".")
и doubleParts.head/tail
может быть связано с дополнительным распределением массива и конкатенацией строк. однако, нужно будет проверить.
– cevaris
10 January 2018 в 22:27
Я бы не использовал BigDecimal, если вы заботитесь о производительности. BigDecimal преобразует числа в строку и затем анализирует их снова:
/** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`, rounding if necessary. */
def decimal(d: Double, mc: MathContext): BigDecimal = new BigDecimal(new BigDec(java.lang.Double.toString(d), mc), mc)
Я буду придерживаться математических манипуляций, поскольку предложил Kaito .
Немного странно, но приятно. Я использую String, а не BigDecimal
def round(x: Double)(p: Int): Double = {
var A = x.toString().split('.')
(A(0) + "." + A(1).substring(0, if (p > A(1).length()) A(1).length() else p)).toDouble
}
Вы можете использовать неявные классы:
import scala.math._
object ExtNumber extends App {
implicit class ExtendedDouble(n: Double) {
def rounded(x: Int) = {
val w = pow(10, x)
(n * w).toLong.toDouble / w
}
}
// usage
val a = 1.23456789
println(a.rounded(2))
}
Изменить: исправлена проблема, о которой указал @ryryguy. (Спасибо!) [/ G0]
Если вы хотите, чтобы это было быстро, Kaito имеет правильную идею. math.pow
медленнее. Для любого стандартного использования вам будет лучше с рекурсивной функцией:
def trunc(x: Double, n: Int) = {
def p10(n: Int, pow: Long = 10): Long = if (n==0) pow else p10(n-1,pow*10)
if (n < 0) {
val m = p10(-n).toDouble
math.round(x/m) * m
}
else {
val m = p10(n).toDouble
math.round(x*m) / m
}
}
Это примерно в 10 раз быстрее, если вы находитесь в диапазоне Long
(т.е. 18 цифр), чтобы вы могли округлить где-то между 10 ^ 18 и 10 ^ -18.
scala> def r5(x:Double) = math.round(x*100000)*0.000001; r5(0.23515)
== & gt; res12: Double = 0.023514999999999998
. Вместо этого разделите значение: math.round(x*100000)/100000.0
– ryryguy
19 April 2013 в 23:37
Вот еще одно решение без BigDecimals
Truncate:
(math floor 1.23456789 * 100) / 100
Round:
(math rint 1.23456789 * 100) / 100
Или для любого двойного n и точности p:
def truncateAt(n: Double, p: Int): Double = { val s = math pow (10, p); (math floor n * s) / s }
Аналогично может быть сделано для функции округления, на этот раз с использованием currying:
def roundAt(p: Int)(n: Double): Double = { val s = math pow (10, p); (math round n * s) / s }
, который более многоразовый, например при округлении денежных сумм можно использовать следующее:
def roundAt2(p: Int) = roundAt(2)(p)
floor
заключается в том, что truncateAt(1.23456789, 8)
вернет 1.23456788
, а roundAt(1.23456789, 8)
вернет правильное значение 1.23456789
– Todor Kolev
23 April 2017 в 21:25
"%.2f".format(x).toDouble
в этом случае. Только в 2 раза медленнее, и вам нужно использовать только те библиотеки, которые вы уже знаете. – Rex Kerr 19 June 2012 в 21:52scala> "%.2f".format(0.714999999999).toDouble
res13: Double = 0.71
, ноscala> "%.2f".format(0.715).toDouble
res14: Double = 0.72
. – Rex Kerr 20 April 2013 в 19:37