Why is DBL_MIN not negative (in Swift)? - swift

Why does the expression DBL_MIN < 0 returns false?
Why do the comparisons against DLB_MIN seem to indicate that DBL_MIN is positive?
let a = DBL_MIN // 2.225073858507201e-308
let b = DBL_MAX // 1.797693134862316e+308
if a < 0.0 {
print("1. DBL_MIN is indeed less than zero") // doesn't print (unexpected)
}
if DBL_MIN < 0.0 {
print("2. DBL_MIN is indeed less than zero") // doesn't print (unexpected)
}
if DBL_MIN > 0.0 {
print("3. DBL_MIN is larger than zero?") // prints (unexpected)
}
if DBL_MIN > DBL_MAX {
print("4. DBL_MIN did some strange flip?") // doesn't print (OK)
}
if b > 0.0 {
print("5. DBL_MAX is indeed larger than zero") // prints (OK)
}
/* printout:
3. DBL_MIN is larger than zero?
5. DBL_MAX is indeed larger than zero */
I suspect it has something to do with floating point precision, but I can't really explain it myself.
I am using Swift 2.1.1 and XCode 7.2.

It is not minimal in the sense that is the largest negative number but the number closest to zero representable as Double:
2.225073858507201 * 10 ^ -308
That simply is a positive value. The - represents a negative exponent, not a negative overall value.

Related

How to produce negative Nan?

I have a "creative" algorithm I'm working on, and there is a case where I need to return negative Nan.
extension Decimal {
func placement(
between gains: Decimal,
and losses: Decimal
) -> Decimal {
if gains == losses {
return self > gains ? (1 / 0) : (-1 / 0)
}
return (self - losses) / (gains - losses)
}
}
Unfortunately (-1 / 0) produces Nan instead of -Nan.
I've accidentally created -Nan previously, unfortunately, I don't remember how it happened.
When something is literally "not a number", how can it have a meaningful sign?
And, from a practical perspective, how do you expect to distinguish "negative NaN" from "NaN"? Decimal.nan == -Decimal.nan is true, as well as Decimal.nan < 0 and -Decimal.nan < 0
let n = Decimal.nan
let nn = -Decimal.nan
print (n < 0) // true
print (nn < 0) // true
print (nn < n) // false
print (n < nn) // false
print (n == nn) // true
print(-Double.nan) // produces -nan
print(-Decimal.nan) // produces Nan
I think Decimal might not track signed nan. It doesn't distinguish between positive and negative nan but if it is negative nan, isNan will produce true.

Round Half Down in Swift

Is there a rounding mode in Swift that behaves same as ROUND_HALF_DOWN in Java?
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. Behaves as for RoundingMode.UP if the discarded fraction is > 0.5; otherwise, behaves as for RoundingMode.DOWN.
Example:
2.5 rounds down to 2.0
2.6 rounds up to 3.0
2.4 rounds down to 2.0
For a negative number:
-2.5 rounds up to -2.0
-2.6 rounds down to -3.0
-2.4 rounds up to -2.0
There is – as far as I can tell – no FloatingPointRoundingRule with the same behavior as Java's ROUND_HALF_DOWN, but you can get the result with a combination of rounded() and nextDown or nextUp:
func roundHalfDown(_ x: Double) -> Double {
if x >= 0 {
return x.nextDown.rounded()
} else {
return x.nextUp.rounded()
}
}
Examples:
print(roundHalfDown(2.4)) // 2.0
print(roundHalfDown(2.5)) // 2.0
print(roundHalfDown(2.6)) // 3.0
print(roundHalfDown(-2.4)) // -2.0
print(roundHalfDown(-2.5)) // -2.0
print(roundHalfDown(-2.6)) // -3.0
Or as a generic extension method, so that it can be used with all floating point types (Float, Double, CGFloat):
extension FloatingPoint {
func roundedHalfDown() -> Self {
return self >= 0 ? nextDown.rounded() : nextUp.rounded()
}
}
Examples:
print((2.4).roundedHalfDown()) // 2.0
print((2.5).roundedHalfDown()) // 2.0
print((2.6).roundedHalfDown()) // 3.0
print((-2.4).roundedHalfDown()) // -2.0
print((-2.5).roundedHalfDown()) // -2.0
print((-2.6).roundedHalfDown()) // -3.0
Swift implements .round() function with rules, According to Apple
FloatingPointRoundingRule
case awayFromZero
Round to the closest allowed value whose magnitude is greater than or equal to that of the source.
case down
Round to the closest allowed value that is less than or equal to the source.
case toNearestOrAwayFromZero
Round to the closest allowed value; if two values are equally close, the one with greater magnitude is chosen.
case toNearestOrEven
Round to the closest allowed value; if two values are equally close, the even one is chosen.
case towardZero
Round to the closest allowed value whose magnitude is less than or equal to that of the source.
case up
Round to the closest allowed value that is greater than or equal to the source.
Yes, You can do the similar things using NSNumberFormatter and RoundingMode
Read them here
NSNumberFormatter
RoundingMode
var a = 6.54
a.round(.toNearestOrAwayFromZero)
// a == 7.0
var b = 6.54
b.round(.towardZero)
// b == 6.0
var c = 6.54
c.round(.up)
// c == 7.0
var d = 6.54
d.round(.down)
// d == 6.0
You can do like this as well but need to take values after decimal as well.
As #MohmmadS said those are built in methods for rounding.
You can implement custom rounding like this:
func round(_ value: Double, toNearest: Double) -> Double {
return round(value / toNearest) * toNearest
}
func roundDown(_ value: Double, toNearest: Double) -> Double {
return floor(value / toNearest) * toNearest
}
func roundUp(_ value: Double, toNearest: Double) -> Double {
return ceil(value / toNearest) * toNearest
}
Example:
round(52.376, toNearest: 0.01) // 52.38
round(52.376, toNearest: 0.1) // 52.4
round(52.376, toNearest: 0.25) // 52.5
round(52.376, toNearest: 0.5) // 52.5
round(52.376, toNearest: 1) // 52

How to print all the digits in a large number of 10 power 25 in swift?

I have been working on a hacker rank problem where I have to print a number which is a factorial of 25. Here is the code I used.
func extraLongFactorials(n: Int) -> Void {
let factorialNumber = factorial(number: n)
var arrayForStorage: [Int] = []
var loop = factorialNumber
while (loop > 0) {
let digit = loop.truncatingRemainder(dividingBy: 10)
arrayForStorage.append(Int(digit))
loop /= 10
}
arrayForStorage = arrayForStorage.reversed()
var returnString = ""
for element in arrayForStorage {
returnString = "\(returnString)\(element)"
}
print(returnString)
}
func factorial(number: Int) -> Double {
if number == 0 || number == 1 {
return 1
} else if number == 2 {
return 2
} else {
return Double(number) * factorial(number: number - 1)
}
}
But when I try to print the factorial number it just prints 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015511210043330982408266888 when it should print
15511210043330985984000000.
I think for a Double number truncatingRemainder(dividingBy: 10) method is not giving me the exact number of the remainder. Because when I tried to print the truncatingRemainder of 15511210043330985984000000 it is giving me as 8. Here is the code.
let number: Double = 15511210043330985984000000
print(number.truncatingRemainder(dividingBy: 10))
So finally I didn't find any solution for the problem of how to split the large number and add it into an array. Looking forward for the solution.
Type Double stores a number as a mantissa and an exponent. The mantissa represents the significant figures of the number, and the exponent represents the magnitude of the number. A Double can only represent about 16 significant figures, and your number has 26 digits, so you can't accurately store 15511210043330985984000000 in a Double.
let number1: Double = 15511210043330985984000000
let number2: Double = 15511210043330985984012345
if number1 == number2 {
print("they are equal")
}
they are equal
You will need another approach to find large factorials like the one shown in this answer.

Big Integer Swift 4.0

I want to perform a big mod (%) operation like the example below:
083123456787654325500479087654 % 55
As you can see this number is bigger than Int64.max (9223372036854775807)
I tried to parse this "083123456787654325500479087654" from string into a Decimal but I can't perform mod operation with two Decimals.
Any suggestions?
You can define a custom mod operator between two decimals such as follow. I haven't the time to test for all scenarios. So I'm selecting the simplest case: modulo between 2 positive numbers. You can expand it to suit your situation:
func % (lhs: Decimal, rhs: Decimal) -> Decimal {
precondition(lhs > 0 && rhs > 0)
if lhs < rhs {
return lhs
} else if lhs == rhs {
return 0
}
var quotient = lhs / rhs
var rounded = Decimal()
NSDecimalRound(&rounded, &quotient, 0, .down)
return lhs - (rounded * rhs)
}
let a = Decimal(string: "083123456787654325500479087654")!
print(a % 55)
The result is 49.

ios how to check if division remainder is integer

any of you knows how can I check if the division remainder is integer or zero?
if ( integer ( 3/2))
You should use the modulo operator like this
// a,b are ints
if ( a % b == 0) {
// remainder 0
} else
{
// b does not divide a evenly
}
It sounds like what you are looking for is the modulo operator %, which will give you the remainder of an operation.
3 % 2 // yields 1
3 % 1 // yields 0
3 % 4 // yields 1
However, if you want to actually perform the division first, you may need something a bit more complex, such as the following:
//Perform the division, then take the remainder modulo 1, which will
//yield any decimal values, which then you can compare to 0 to determine if it is
//an integer
if((a / b) % 1 > 0))
{
//All non-integer values go here
}
else
{
//All integer values go here
}
Walkthrough
(3 / 2) // yields 1.5
1.5 % 1 // yields 0.5
0.5 > 0 // true
swift 3:
if a.truncatingRemainder(dividingBy: b) == 0 {
//All integer values go here
}else{
//All non-integer values go here
}
You can use the below code to know which type of instance it is.
var val = 3/2
var integerType = Mirror(reflecting: val)
if integerType.subjectType == Int.self {
print("Yes, the value is an integer")
}else{
print("No, the value is not an integer")
}
let me know if the above was useful.
Swift 5
if numberOne.isMultiple(of: numberTwo) { ... }
Swift 4 or less
if numberOne % numberTwo == 0 { ... }
Swift 2.0
print(Int(Float(9) % Float(4))) // result 1