.getBytes() in Swift 1.2 gives trouble - xcode6

In Swift 1.2, I am trying to compile the md5 implementation that I found on rosettacode.
One single line gives me an error and I cannot figure out why.
This is the line:
chunk.getBytes(M[x], range:range)
This is the error I get:
Cannot invoke 'getBytes' with an argument of type'(UInt32, range: _NSRange)'
And this is the context:
// break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
let wordSize = sizeof(UInt32)
var M:[UInt32] = [UInt32](count: 16, repeatedValue: 0)
for x in 0..<M.count {
var range = NSRange(location:x * wordSize, length: wordSize)
chunk.getBytes(M[x], range:range)
}
(BTW, the same line worked well in the previous version of Swift)
Thanks for any insight!

The code that works in Swift 1.1 is (note the & operator):
chunk.getBytes(&M[x], range:range)
but this does indeed not compile anymore with Swift 1.2.
You can replace the line with the equivalent code
withUnsafeMutablePointer(&M[x]) { chunk.getBytes($0, range:range) }
or use a temporary variable
var tmp = UInt32(0)
chunk.getBytes(&tmp, range:range)
M[x] = tmp
to make it work again.
But note that the loop is actually not needed at all, and your
code can be simplified to
let wordSize = sizeof(UInt32)
var M = [UInt32](count: 16, repeatedValue: 0)
chunk.getBytes(&M, length: M.count * wordSize)
which compiles with Swift 1.1 and 1.2.

Related

Wrong comparing of Double and Int numbers in Kotlin

I'm working on calculator project but when I tried to use two similar ways of comparing double and int numbers I got different results.
So my question is Why are these ways of comparing works differently?
//some code that parse the string
//...
//code of calculating:
fun calculateIn(queueNumbers: Queue<Double>, queueActions: Queue<Char>) {
var action: Char
var result = queueNumbers.poll()
var operand: Double
while (!queueNumbers.isEmpty()) {
operand = queueNumbers.poll()
action = queueActions.poll()
when (action) {
'-' -> result -= operand
'+' -> result += operand
'*' -> result *= operand
'/' -> result /= operand
'%' -> result = result % operand * -1.0
}
}
var pointNum = 8.3
println("pointNum = " + pointNum)
println(if(pointNum.compareTo(pointNum.toInt()) == 0) pointNum.toInt() else pointNum)
println("result = " + result)
println(if(result.compareTo(result.toInt()) == 0) result.toInt() else result)
}
Result of code:
"10.3 + -2" //input String
[10.3, -2.0] //queueNumbers
[+]//queueActions
pointNum = 8.3
8.3
result = 8.3
8
I think that is strange because if I run similar code I will get the correct result:
var pointNum = 8.3
println(if(pointNum.compareTo(pointNum.toInt()) == 0) pointNum.toInt() else pointNum)
So there is result of this code:
8.3
Full code on GitHub: https://github.com/Trilgon/LearningKotlin
I believe this is a bug in the compiler. Discussion is here, I copy my findings:
Minimal reproducible example:
fun test1(): Int {
val d: Double?
d = 8.3
return d.compareTo(8) // 0
}
fun test2(): Int {
val d: Double
d = 8.3
return d.compareTo(8) // 1
}
Technical difference between these two code samples is that the value is boxed in test1() and unboxed in test2(). If we look at the generated bytecode for test2(), everything looks as expected:
7: bipush 8
9: i2d
10: invokestatic #63 // Method java/lang/Double.compare:(DD)I
It converts integer value 8 to double and then compares both values as doubles.
But if we look into test1(), something bizarre happens there:
10: invokevirtual #52 // Method java/lang/Double.doubleValue:()D
13: d2i
14: bipush 8
16: invokestatic #58 // Method kotlin/jvm/internal/Intrinsics.compare:(II)I
It does the opposite: it converts double value 8.3 to integer and then compares values as integers. This is why it says values are the same.
What is interesting, even "Kotlin Bytecode" tool in IntelliJ shows the correct code for test1():
INVOKEVIRTUAL java/lang/Double.doubleValue ()D
BIPUSH 8
I2D
INVOKESTATIC java/lang/Double.compare (DD)I
But the real generated bytecode is different and gives different results.
I reported the problem: https://youtrack.jetbrains.com/issue/KT-52163
This was a weird and even funny problem to me, But I think I found out what's the problem.
In Kotlin Double class is defined inside Primitives.kt, well at least in the build-in files not in the actual source. Here Double class implements an interface named Comparable<Double> which is another built-in Kotlin file. You can see a portion of that interface:
public operator fun compareTo(other: T): Int
So let's return to your code. I suspend culprit of this problem is the very first line.
import java.util.*
Inside the java.util package there is another Comparable interface, I think since Queue is a Java class and the poll method may return a nullable value, and since you already imported everything inside java.util package then compareTo is called from Comparable from java.util not the one in Kotlin package.
The reason why Java's compareTo returns a different result is unknown to me.
I tried replacing java.util.* with:
import java.util.Queue
import java.util.LinkedList
But nothing changed.
However, I found another solution, just replace var result = queueNumbers.poll() with var result = queueNumbers.poll() ?: 0.0 or var result: Double = queueNumbers.poll() then it would be fixed!
//original
var result = queueNumbers.poll()
//method 1
var result : Double = queueNumbers.poll()
//method 2
var result = queueNumbers.poll() ?: 0.0

How do i make a loop like mentioned below in kotlin programming language?

How can I make it in kotlin using for loop?
for (double i = 0; i < 10.0; i += 0.25) {
System.out.println("value is:" + i);
}
You should use the Intellij plugin for converting Java code for Kotlin. It's pretty neat (unless you have complex code using lambdas) This is what it converts to for your given question:
var i = 0.0
while (i < 10.0) {
println("value is:" + i)
i += 0.25
}
Here is the kotlin code equivalent to for loop.
var i = 0.0
while (i < 10.0)
{
println("value is:" + i)
i += 1.0
}
Kotlin for loop only support iterate the arrays.Please refer https://kotlinlang.org/docs/reference/control-flow.html
It's achievable in different way
var length:Double = 10.0
var increment:Double = 0.25
for (index in Array((length/increment).toInt(), { i -> (i * increment) }))
println(index)
I'm not sure if this syntax is new, but natural numbers may be used to iterate values like so.
(0..(10*4)).map {
it / 4.0 as Double
}.forEach {
println(it)
}
I'm avoiding iteration on IEEE 754 floating points, as that could potentially cause errors. It may be fine in this case, but the same may not be true depending on environment, context, and language. It's best to avoid using floating point except in cases where the numbers are expected to have arbitrary precision, i.e. uses real numbers or continuity.
This syntax may be used within a for loop as well if you don't need to store the result. However, for loops should be avoided for the most part if you want immutability (which you should).
for (i in 0..10) {
println("Project Loom is a lie! $i")
}

CUnsignedChar has no subscript members

I am getting the error Type 'CUnsignedChar?' has no subscript members which produces a lot of results in stackoverflow however I can't seem to utilise any of the other available answers for my example. Its clearly a casting issue but I don't not see how to overcome it
I am doing a obj-c to swift conversion and I have a variable being set up as follows
var bBuff1 = [CUnsignedChar](repeating: 0, count: Int(256*512))
var backGreyBuffer : CUnsignedChar = bBuff1[0]
//..
//..
var backGreyBufferOffset : Int = localTexOffset * 512
var grey_val = 0
self.backGreyBuffer[Int(backGreyBufferOffset)]! = grey_val; //Subscript error here
This is the obj-c code that uses in-outs.
unsigned char bBuff1[256*512];
unsigned char *backGreyBuffer = &bBuff1[0];
//..
grey_val = 0;
backGreyBuffer[backGreyBufferOffset] = grey_val;
Any suggestions about the right direction would be great.
I noticed that only a small change is needed in your code. You should make backGreyBuffer a pointer:
var bBuff1 = [CUnsignedChar](repeating: 0, count: Int(256*512))
var backGreyBuffer = UnsafeMutablePointer(mutating: bBuff1)
// ....
var backGreyBufferOffset = localTexOffset * 512
backGreyBuffer[backGreyBufferOffset] = grey_val

SKTUtils Errors Galore

Added SKTUtils to my project and it just does not want to cooperate. I am afraid to change too much as I assumed it is coded a very specific way. Here is a few errors that I am getting and cannot figure out. Returning 20 errors then says too many errors, stopping now.
These return: "incompatible block pointer types initializing'_strong SKTTiming Function' AKA 'float(^_strong)(float) with an expression of type 'void'(^)(float)
Use of undeclared identifier 'M_PI_2',M_Pi
Implicitly declaring library function 'sqrtf' with type float(float)
SKTTimingFunction SKTTimingFunctionSineEaseIn = ^(float t) {
return sinf((t - 1.0f) * M_PI_2) + 1.0f;
};
SKTTimingFunction SKTTimingFunctionSineEaseOut = ^(float t) {
return sinf(t * M_PI_2);
};
SKTTimingFunction SKTTimingFunctionSineEaseInOut = ^(float t) {
return 0.5f * (1.0f - cosf(t * M_PI));
};
SKTTimingFunction SKTTimingFunctionCircularEaseIn = ^(float t) {
return 1.0f - sqrtf(1.0f - t * t);
};
Sounds like an old version of SKTUtils? M_Pi is no longer used.
I just created an Xcode 7.3.1 SpriteKit project and dropped in a clean SKTUtils, no issues.
SKUtils was updated not so long ago for 7.3
https://github.com/raywenderlich/SKTUtils

how to overcome CString error

how to overcome this error
func selectFunc(){
var selectQuery="select * from EmployeInfo"
var cSql:CString = selectQuery.bridgeToObjectiveC().cStringUsingEncoding(NSUTF8StringEncoding)
var result:CInt=0
var stmt:COpaquePointer = nil
result = sqlite3_prepare_v2(appDelegate.database, cSql, -1, &stmt, nil);
if result != SQLITE_OK
error occurred use of undeclared CString.how to overcome this error
In older Swift versions (before Xcode 6 beta 6), a Swift String had explicitly to be converted
when passed to a C function taking a const char * argument, as in your code.
This is no longer necessary. The CString type and the bridgeToObjectiveC() method do not exist anymore.
The current Swift compiler does the conversion
automatically (compare String value to UnsafePointer<UInt8> function parameter behavior) and you can just write
let selectQuery = "select * from EmployeInfo"
var stmt : COpaquePointer = nil
let result = sqlite3_prepare_v2(appDelegate.database, selectQuery, -1, &stmt, nil)