What's the best way to do math with CGFloats in swift? - math

I tried to do some simple UIView layout math in swift and tried the following line of code...
var offset: CGFloat = (bounds.width / 2.0) - ((sortedSymptoms.count * bounds.height) / 2.0)
and got the following error from the compiler:
cannot invoke '-' with an argument list of type '(($T6), ($T17))'
var offset: CGFloat = (bounds.width / 2.0) - ((sortedSymptoms.count * bounds.height) / 2.0)
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The compiler error isn't all that helpful, but it looks like there's a type conflict between Double, Int, and CGFloat of some kind. I was able to get the line to compile by sprinkling in some explicit creations of CGFloats, but I can't believe that this is the right way to do this.
var offset: CGFloat = (bounds.width / CGFloat(2.0)) - ((CGFloat(sortedSymptoms.count) * bounds.height) / CGFloat(2.0))
What's the right way?

This is a known issue in Swift and the dev team has been working on improving the issue around CGFloat in particular. But at this time, yes, that's how you write it.
Some followup from devforums (which may make you happy or sad, but at least roughly explains the current status): https://devforums.apple.com/message/1026028#1026028
Note that the main issue here is that the literal 2.0 doesn't coerce to CGFloat, which it arguably should. But count will likely always require a cast, by intent. You cannot always safely convert between numeric types, and Swift intentionally forces you to consider each time you do these kinds of casts. But it should be possible to determine if a literal conversion is safe at compile-time, so that should be fixable.

Related

sum(ofProperty: "amount") giving error in swift 5

I am using swift5 and I am trying to sum by property like this:
let total = realm.objects(Purchase.self).sum(ofProperty: "amount")
but i get this error:
Type of expression is ambiguous without more context
what can I do?
Probably the easist solution is to let the compiler know what kind of result the sum will be.
Like this
let total: Double = realm.objects(Purchase.self).sum(ofProperty: "orderProperty")
print(total)
This tells the compiler than total will always be a Double
As a side note, Double's are (generally) not a good type to work with for financial situations. Look into Decimal (akin to NSDecimal and Decimal128)
#Persisted var decimal: Decimal128
in newer versions

In GDB Python script, array indexing fails if frame’s language is Ada

I have a script to work out how much free stack space there is in each FreeRTOS task. GDB’s language is set to auto. The script works fine when the current language is c, but fails when the current language is ada.
I have, in the class Stacks,
tcb_t = gdb.lookup_type("TCB_t")
int_t = gdb.lookup_type("int")
used to:
find {Ada task control block}.Common.Thread,
thread = atcb["common"]["thread"]
convert to a pointer to the FreeRTOS task control block,
tcb = thread.cast(Stacks.tcb_t.pointer()).dereference()
find the logical top of the stack
stk = tcb["pxStack"].cast(Stacks.int_t.pointer())
Now I need to loop logically down the stack until I find an entry not equal to the initialised value,
free = 0
while stk[free] == 0xa5a5a5a5:
free = free + 1
which works fine if the current frame’s language is c, but if it’s ada I get
Python Exception <class 'gdb.error'> not an array or string:
Error occurred in Python command: not an array or string
I’ve traced this to the expression stk[free], which is being interpreted using the rules of the current language (in Ada, array indexing uses parentheses, so it would be stk(free), which is of course illegal since Python treats it as a function call).
I’ve worked round this by
def invoke(self, arg, from_tty):
gdb.execute("set language c")
...
gdb.execute("set language auto")
but it seems wrong not to set the language back to what it was originally.
So,
is there a way of detecting the current GDB language setting from Python?
is there an alternate way of indexing that doesn’t depend on the current GDB language setting?

difference between * and ^ in c++\c?

I have this code:
DispatcherTimer^ CalenderClock();
When I use * instead of ^ visual studio tells me:
an ordinary pointer to C++\CX mapping ref class or inteface class is not allowed
what is the difference between ^ and * pointers?
The handle-to-object operator ^ is known as a "hat" and is fundamentally a C++ smart pointer. The memory it points to is automatically destroyed when the last hat goes out of scope or is explicitly set to nullptr.
Source: https://learn.microsoft.com/en-us/cpp/cppcx/ref-classes-and-structs-c-cx (Found by googling your error message.)
Note that this syntax is non-standard. It is a Microsoft extension to the C++ language.

Matlab: Attempt to reference field of non-structure array

I am using the Kernel Density Estimator toolbox form http://www.ics.uci.edu/~ihler/code/kde.html . But I am getting the following error when I try to execute the demo files -
>> demo_kde_3
KDE Example #3 : Product sampling methods (single, anecdotal run)
Attempt to reference field of non-structure array.
Error in double (line 10)
if (npd.N > 0) d = 1; % return 1 if the density exists
Error in repmat (line 49)
nelems = prod(double(siz));
Error in kde (line 39)
if (size(ks,1) == 1) ks = repmat(ks,[size(points,1),1]); end;
Error in demo_kde_3 (line 8)
p = kde([.1,.45,.55,.8],.05); % create a mixture of 4 gaussians for
testing
Can anyone suggest what might be wrong? I am new to Matlab and having a hard time to figure out the problem.
Thank You,
Try changing your current directory away from the #kde folder; you may have to add the #kde folder to your path when you do this. For example run:
cd('c:\');
addpath('full\path\to\the\folder\#kde');
You may also need to add
addpath('full\path\to\the\folder\#kde\examples');
Then see if it works.
It looks like function repmat (a mathworks function) is picking up the #kde class's version of the double function, causing an error. Usually, only objects of the class #kde can invoke that functions which are in the #kde folder.
I rarely use the #folder form of class definitions, so I'm not completely sure of the semantics; I'm curious if this has any effect on the error.
In general, I would not recommend using the #folder class format for any development that you do. The mathworks overhauled their OO paradigm a few versions ago to a much more familiar (and useful) format. Use help classdef to see more. This #kde code seems to predate this upgrade.
MATLAB gives you the code line where the error occurs. As double and repmat belong to MATLAB, the bug probably is in kde.m line 39. Open that file in MATLAB debugger, set a breakpoint on that line (so the execution stops immediately before the execution of that specific line), and then when the code is stopped there, check the situation. Try the entire code line in console (copy-paste or type it, do not single-step, as causing an uncatched error while single-stepping ends the execution of code in debugger), it should give you an error (but doesn't stop execution). Then try pieces of the code of that code line, what works as it should and what not, eg. does the result of size(points, 1) make any sense.
However, debugging unfamiliar code is not an easy task, especially if you're a beginner in MATLAB. But if you learn and understand the essential datatypes of MATLAB (arrays, cell arrays and structs) and the different ways they can be addressed, and apply that knowledge to the situation on the line 39 of kde.m, hopefully you can fix the bug.
Repmat calls double and expects the built-in double to be called.
However I would guess that this is not part of that code:
if (npd.N > 0) d = 1; % return 1 if the density exists
So if all is correct this means that the buil-tin function double has been overloaded, and that this is the reason why the code crashes.
EDIT:
I see that #Pursuit has already addressed the issue but I will leave my answer in place as it describes the method of detection a bit more.

Global variable touched by a passed-in parameter becomes unusable

folks!
I pass a struct full of data to my kernel, and I run into the following difficulty using it (very stripped down):
[edit: mac osx / xcode 3.2 on mac book pro; this compile is obviously for cpu]
typedef struct
{
float xoom;
int sizex;
} varholder;
float zX, xd;
__kernel void Harlan( __global varholder * vh )
{
int X = get_global_id(0), Y = get_global_id(1);
zX = ( ( X - vh->sizex/2 ) / vh->xoom + vh->sizex/2 ); // (a)
xd = zX; // (b) BOOM!!
}
after executing line (a), the line marked (b), a simple assignment, gives "LLVM compiler failed to compile a function".
if, however, we do not execute line (a), then line (b) is fine.
So, through my fiddling around a LOT with this, it seems as if it is the assignment statement (a), which uses a passed-in parameter, that messes up the future access of the variable zX. However, of course I need to be able to use the results of calculations further down the line.
I have zX and xd declared at the file level because my helper functions need them.
Any thoughts?
Thanks!
David
p.s. I'm now registered so will be able to upvote and accept answers, which I am sadly unable to do for the last person who helped me (used same username to register, but can't seem to vote on the old post; sorry!).
No, say it ain't so!
I am sincerely hoping that this is not a "correct" answer to my own question. I found on another forum (though not the same question asked!) the following, and I am afraid that it refers to what I'm trying to do:
(quote)
You're doing something the standard prohibits. Section 6.5 says:
'All program scope variables must be declared in the __constant address space.'
In other words, program scope variables cannot be mutable.
(end quote)
... well, tcha!!!! What an astoundingly inconvenient restriction! I'm sure there's reasoning behind it.
[edit: Not At All inconvenient! it was in fact astonishingly easy to work around, given a fresh start the next morning. (And no alcohol.)]
You guys & dolls all knew this, right, and didn't have the heart to tell me?...

Resources