Zum Thema Division und TI

    „Mach dich nicht stolz, Maria Ivanovna, und höre dein Lieblingslied“ Valenki ”



    Trotz des Titels wird die Reihenfolge der Präsentation umgekehrt - zuerst über Texas Instruments (natürlich nicht über das Unternehmen selbst, ich bin ein Ingenieur, kein Business-Analyst- Trainer , also über die von dem Unternehmen hergestellten Produkte) und erst dann über die Spaltung.

    Der erste Teil des Marlezonsky-Balletts.

    Es wird eine relativ neue Familie CC13xx (CC1310 / CC1350 / CC1352) angesprochen, die jedoch nur der Ausgangspunkt für die Erörterung der Situation im Bereich der Programmierung eingebetteter Systeme ist. Der in Betracht gezogene MK ist für die Verwendung bei der Entwicklung von Geräten mit verschiedenen Arten von drahtlosen Schnittstellen vorgesehen (das neuartige IoT gefällt mir nicht wirklich, zumal es die Einsatzmöglichkeiten dieser Familie nicht erschöpft).

    Der MC ist auf der Basis des M3-Kerns mit recht akzeptablen, aber nicht aufnehmbaren Parametern der Frequenz und der Menge an Programmspeicher und Daten aufgebaut, verfügt über eine ausreichende Anzahl von Schnittstellen, diese sind jedoch überhaupt nicht interessant. Das Merkmal ist, dass der Mikrokreislauf drei MK-Kerne in sich enthält, einen zentralen und zwei peripheren - für die Arbeit mit externen Geräten und für die Interaktion durch den Äther. Was hat zu einer solchen Entscheidung geführt?

    Vor allem der Wunsch, einen minimalen Energieverbrauch zu gewährleisten. Tatsache ist, dass der traditionelle Weg zur Verringerung des Verbrauchs durch ressourcenintensive Berechnungen in relativ kurzer Zeit und anschließendes Wechseln in den Standby-Modus mit einer Abnahme der Taktfrequenz natürliche Einschränkungen aufweist und ein schneller Kern bei einer niedrigeren Frequenz relativ viel verbraucht, ohne jedoch die erforderliche Antwortzeit bereitzustellen externe Ereignisse. Um diesen Widerspruch zu beseitigen, wurde der zweite Kern des Sensor-Controllers eingeführt, der im verbrauchsarmen Modus die Interaktion mit der Außenwelt ermöglicht und bei ressourcenintensiven Berechnungen den Hauptkern aktiviert.

    Der dritte Controller löst (wenn auch sehr kompliziert) die gleiche Aufgabe, den Verbrauch zu reduzieren. Die Tatsache ist, dass das Aufrechterhalten von Funkprotokollen oft die Aufrechterhaltung sehr enger Zeitbeschränkungen erfordert und der Versuch, sie im zentralen Kern (gleichzeitig mit der Ausführung des Zielprogramms) zu implementieren, erfordert eine Erhöhung der Kerntaktfrequenz und dementsprechend den von der Stromquelle aufgenommenen Strom. Durch die Aufteilung der Funktionen können wir diesen Widerspruch (eine typische Lösung im Stil von TRIZ) aufheben.

    Ich bin mir keineswegs sicher, dass eine solche Funktionsteilung absolut notwendig war und dass die erforderlichen Parameter mit einfacheren architektonischen Lösungen nicht erreicht werden könnten. Wenn der Preis jedoch in vernünftigen Grenzen gehalten wird und die erforderlichen Möglichkeiten geschaffen werden, warum dann nicht. Darüber hinaus handelt es sich bei dem Beitrag immer noch nicht um die Hardwarekomponente des MC, sondern lediglich um die Situation abzudecken. Wir werden den Prozess der Erstellung von Software für diese Klasse MK betrachten.

    Zunächst einmal - der Hauptkern, hier ist alles Standard - und der M3-Kern selbst ist bekannt, und der Tulchan-Gcc empfiehlt zwei IDE-ccs und iar. Ich habe viel mit den letzten von ihnen gearbeitet, also entschied ich mich zu versuchen, welches Produkt das düstere Teutonic-Genie hervorbrachtekollektiver Verstand ti. Code Composer Studio ist eine Entwicklungsfirma und ist ohne Einschränkungen absolut kostenlos, basierend auf (wer hätte gedacht) Eclipse und hat alle Vor- und Nachteile, die dieser Umgebung innewohnen.

    Das einzige, worüber ich sofort meine Verwirrung zum Ausdruck bringen möchte - das Unternehmen bietet freundlicherweise zusätzliche Hilfsprogramme für die Arbeit mit diesem MK (zum Erzeugen eines Boot-Firmware-Images über Funk und zum Übertragen an MK), aber sie sind aus irgendeinem Grund nicht in Java geschrieben. Dies ist die Basis für die Programmierumgebung und das ausführende System, für das das Installationspaket enthalten ist, und auf dem Phyton. Nicht, dass ich das letztere nicht sehr mochte (obwohl ich die Aufgabe der Programmstruktur mit Einrückungen nicht akzeptiere, aber letztendlich „der Geschmack und die Farbe aller Farben sind unterschiedlich“), ist es einfach nicht klar, warum man eindeutig unnötige Elemente anzieht. Und die Dienstprogramme selbst stellen nichts Kompliziertes dar.später Funtik F beachten ...).

    Der zweite Teil des Puzzles ist, dass Eclipse selbst beliebt ist, auch dank der Möglichkeit, Plug-Ins einfach einzubetten. Angesichts dieser Tatsache sieht die Entscheidung der Entwickler der Programmierumgebung äußerst geheimnisvoll aus, den Benutzer zu zwingen, diese Dienstprogramme mit Ziehpunkten von der Befehlszeile aus aufzurufen, zuerst das Terminal mit den Ziehpunkten in der Entwicklungsumgebung zu trennen und das Programm zu starten, um Daten auf dem MC zu empfangen, und dann das Terminal mit den Ziehpunkten erneut wiederherstellen. Für hinduistische Programmierer scheint diese Lösung die einzig mögliche und völlig gerechtfertigt zu sein, aber eine große Firma könnte es sich leisten, mehr qualifiziertes Personal zu gewinnen, ich weiß wahrscheinlich nichts.

    Die Programmierung des Sensorcontrollers (der Name ist nicht sehr gut, dies ist jedoch eine direkte Nachverfolgung) wird mit dem Produkt Sensor Composer Studio durchgeführt. Gleich eine andere Frage - warum brauchen wir ein separates Produkt, nicht, dass es sehr schwierig war, das Fenster zu wechseln, aber trotzdem ... vor allem, da der generierte Code schließlich Teil des Codes für den Haupt-MK wird (natürlich ist er da) wird nicht ausgeführt, ist jedoch im allgemeinen Adressraum des Programmspeichers enthalten).

    Eine weitere Besonderheit ist, dass sie uns nichts über diesen Kern (über seine Architektur) sagen, außer dass er 16-Bit, wenig Verbrauch und eine eigene ist. Im Allgemeinen ist das in Ordnung, es funktioniert und funktioniert gut, aber das Sediment bleibt. Das Folgende ist eine Beschreibung der Befehle dieses Kernels. Es kann davon ausgegangen werden, dass es sich um eine Modifikation von 430 handelt, jedoch mit Funktionen wie Schleifenbefehlen. Die Position der peripheren Register im allgemeinen und lokalen Adressraum ist angegeben, aber dann beginnen die Oddities erneut - viele Register, einschließlich der peripheren Register, werden von der Phrase "nur von der TI-Bibliothek verwendet" begleitet, und für einige der Register ist die Zuordnung der Bitfelder noch gegeben manche sind es nicht. Es ist nicht so, dass diese Registerbeschreibungen mir sehr weh tun, aber warum

    Auf die Peripherie dieses Kernels kann vom Hauptkern aus mit speziellen Bibliotheken zugegriffen werden. Gleichzeitig können Sie in der genannten Programmierumgebung Code schreiben, wobei wiederum bestimmte Plug-Ins verwendet werden. Hier ist alles normal, die Dokumentation ist ausreichend, die Einstellungen sind bequem, es gibt eine grafische Darstellung der Einstellungen, das eingebaute Debuggen in einem speziellen Modus (im allgemeinen Modus ist der Debugger vom Hauptkern belegt), im Allgemeinen recht anständig.

    Der nächste Teil ist der Kern für die Arbeit mit Funk, der auf der Basis von M0 aufgebaut ist und das Programm von seinem eigenen ROM aus ausführt (höchstwahrscheinlich Teil des nichtflüchtigen Speichers, es ist unwahrscheinlich, dass ein moderner Speicher einen maskierten Speicher hat), der nicht geändert werden kann (zumindest in diesem Fall) Dokumentation kein Wort) durch den Benutzer. Informationen über die interne Struktur des Funkpfads sind äußerst knapp, sie können nur aus der Beschreibung der Moduseinstellungsbefehle extrahiert werden, aber der gewöhnliche "eingebettete" Entwickler benötigt sie nicht.

    Die Interaktion zwischen dem Hauptkern und dem Funkteil basiert auf dem Nachrichtenfluss, der ausreichend detailliert dokumentiert ist. Und diese Dokumentation reicht aus, um die einfache Sache zu verstehen - Sie werden (also ich werde es definitiv nicht tun) Ihre Interaktionsmechanismen zwischen den Kernen und noch mehr die Kommunikationsprotokolle aufbauen, und Sie werden die von der Firma implementierte Bibliothek verwenden, da die Interaktion selbst mit ziemlich schwierig ist Das Design sollte eine Vielzahl verschiedener Faktoren berücksichtigen, so dass die Vorteile des Schreibens eines eigenen Pakets die Kosten seiner Erstellung nicht ausgleichen. Daher verwenden wir erneut die Bibliotheksunterschicht, um die Interaktion des Hauptkerns mit dem Funkkern zu organisieren, und höchstwahrscheinlich verwenden wir fertige Lösungen zum Organisieren eines standardisierten Funkkanals mit vorgefertigten Modulen, wobei nur die Kanalparametrisierung verwendet wird.

    Ich denke, dem Leser ist klar geworden, dass das Schreiben eines vollwertigen Programms für diesen MC keine leichte Aufgabe ist, für fortgeschrittene Profis durchaus zugänglich ist, aber was man mit einem "normalen" Entwickler machen soll (wie Oleg Artamonov kürzlich schrieb): "Sie haben bereits festgestellt, dass Sie sich sehr geirrt haben Beruf? "). Das Unternehmen hat sich um einen solchen Fall gekümmert und stellt zusammen mit der Entwicklungsumgebung ein umfangreiches Paket (eine Reihe von Beispielen) für alle Anlässe bereit, genannt SimpleLink. Darüber hinaus werden die Lösungen in zwei Versionen angeboten - sowohl mit dem Echtzeitbetriebssystem TI-RTOS (meiner Meinung nach ist dies ein bequemer Weg) als auch im Superzyklus (falls Sie das eingebaute Betriebssystem hassen, das Sie nicht essen können.) “). Ich behandle RTOS ruhig bei MK, also wende ich die erste Option an und empfehle Ihnen, dasselbe zu tun.

    Meine persönliche Einstellung zu diesem Paket ist ambivalent - zum einen ist es ein wunderbares Unterfangen, das die Verwendung von MK wirklich drastisch vereinfacht (daher benutze ich es), aber andererseits "Thrash, Waste and Sodomy" ist ein hervorragendes Beispiel für den Ausdruck "Wenn die Kosten einer guten Architektur scheinen." Sie sind hoch, denken Sie über die Kosten einer schlechten Architektur nach "(ich beschuldige ihn also). Es geht nicht nur um die Verteilung der Funktionen zwischen den Modulen und die Beziehungen zwischen ihnen (obwohl dies nicht alles reibungslos ist), sondern auch um die Verteilung der Module nach Datei, Dateinamen und Verteilung Dateien zu Verzeichnissen und deren Namen und Struktur usw. usw. Aber eine Verletzung der Prinzipien von KISS und DRY ist für Entwickler von Paketen fast eine Regel, aber wenn Sie nicht in die Quelle des Pakets geraten, kann ich diese dumme Angewohnheit nicht loswerden. und verwenden Sie es "wie es ist",

    Aber jetzt können Sie problemlos zum Hauptpostulat dieses Beitrags wechseln (besser spät als nie). Ich habe immer daran geglaubt, dass es extrem schwierig ist, ein Framework zu schreiben, das echte Vielseitigkeit und hohe Effizienz vereint. Die von der Firma vorgeschlagenen Konstruktionsbeispiele stellen einen solchen Rahmen dar, der auf Vielseitigkeit Wert legt. Die Anwendungskonfigurationstools fehlen nahezu vollständig, und dies alles auf der Ebene der Korrektur von Quark. Nehmen Sie eines unserer vielen Beispiele, ändern Sie ein kleines Stück, das mit Messungen und Analysen zusammenhängt (natürlich mit der Übertragung), und alles ist fertig. Natürlich ist der resultierende Code im Allgemeinen ziemlich aufgebläht, aber wir werden Ihnen verschiedene Beispiele für verschiedene Anwendungsbedingungen anbieten, und Sie müssen nur das für Ihre Aufgabe am besten geeignete auswählen. Zur Not, Der MC verfügt über eine ausreichend große Menge an Programmspeicher, sodass Sie nicht daran denken müssen, diese Ressource zu sparen. Darüber hinaus ist ein erheblicher Teil der ausführenden Bibliotheken bereits im ROM versteckt und Sie müssen sie nur sorgfältig aufrufen.

    Nicht, dass ich gegen einen solchen Ansatz war und kategorisch auf der Erfindung von Fahrrädern bestand, ist die Wiederverwendung von Code ein kategorischer Imperativ und eine Garantie für eine hohe Effizienz der Arbeit eines Programmierers. Wenn jedoch die folgende Bedingung erfüllt ist
    , sollte die verwendete Unterprogrammbibliothek lauten:

    1. sorgfältig entworfen
    2. ordentlich programmiert
    3. ausführlich dokumentiert
    4. universell
    5. wirksam.

    Und wenn die letzten beiden Punkte nur wünschenswert sind (sehr wünschenswert, aber trotzdem ...), dann sind die ersten drei Punkte notwendig.

    Und wie sieht es mit den Anforderungen des Pakets aus, das von der Firma SimpleLink angeboten wird? Ferner werden Schätzungen auf einer Fünf-Punkte-Skala angegeben, die in der Reihenfolge der oberflächlichen Vertrautheit mit dem Paket erhalten werden.

    1a) Die Verknüpfungen zwischen den Modulen sollten durchdacht werden, die Grenzen der Kompetenz jedes Moduls sollten klar umrissen werden, wodurch Doppelungen von Funktionen vermieden und Schnittstellen entwickelt werden - solide vier, die gesamte Arbeit wird ausgeführt.

    1b) Verteilung von Modulen durch Dateien mit einer durchdachten Verzeichnisstruktur - eher drei mit einem Plus, was nur wiederholte Wiederholungen des Textes von Programmmodulen in verschiedenen Dateien wert ist.

    2. Ein Paket sollte keine schwer zu erkennenden, selten offensichtlichen Fehler aufweisen (die Tatsache, dass es keine ständig offensichtlichen Fehler geben sollte, liegt auf der Hand). Es ist schwierig, hier Bewertungen abzugeben, ich möchte einen unangenehmen Umstand feststellen - die meisten Funktionen können sowohl aus dem üblichen Programmspeicher als auch aus dem permanenten Speicher hervorgerufen werden. Wenn der Quellcode der ersten Variante verfügbar und validiert ist, ist die zweite sehr viel schlechter - wir erhalten keine Anweisungen seine Quelle, nicht auf die Identität mit der ersten Option, so dass die Überprüfung nicht in Frage kommt.

    3. Dokumentation für eine solide Vier - selbst wenn die Autoren Doxysgens „Macht und Ausdruckskraft“ nicht in Bezug auf die Dokumentation verwendet haben, gibt es mindestens einen Punkt, es gibt ein System kontextbezogener Verknüpfungen, es gibt Beschreibungen der Operationsprinzipien - ich möchte die fünf nicht einfach nur in Bezug auf die Dokumentation nennen Ich habe es nie selbst gestellt.

    4. Nicht mehr als vier wegen der fehlenden Konfiguration, aber ich habe dies bereits erwähnt.

    5. Es ist schwer zu sagen, ich betrachte normalerweise die Implementierung von SPI - es ist einerseits einfach genug, um das Fehlen eines Standardrechens zu erkennen, andererseits ist es schwierig genug, um sie zu stopfen. In diesem Paket gibt es daher ineffiziente Prozeduren zum Schreiben / Lesen von Bytes. Wenn Sie jedoch in die Tiefen eintauchen, finden Sie die Optionen, die tatsächlich mit dem PDP verwendet werden. Bisher kann ich dazu nichts sagen.

    Eine Anmerkung zu den Tiefen - sie sind wirklich tief (nach 4-5 verschachtelten Funktionen) und hier kann ich eine Besonderheit des Pakets erwähnen - es ist in C geschrieben. Ich habe nicht vergessen, nach dem Buchstaben zwei Pluspunkte hinzuzufügen, es ist wirklich nicht da. Für diejenigen, die sich mit dem Thema befassen, wird vieles klar: Ich empfehle allen anderen, sich auf faszinierende Weise zu informieren, welche Funktionen auf Hardwareebene ausgeführt werden, wenn ein nicht triviales Objekt implementiert wird. Wenn Sie Klassen verwenden, wird diese Aufgabe natürlich trivial, aber so ist der Ted Jedi nicht. Ich verstehe, dass dies eine erzwungene Fürsorge für die Benutzer ist, die die Vorteile vernachlässigen, aber warum aufhören, aber was ist mit den unglücklichen Benutzern des Assemblers, für die sie beleidigt wurden.

    Und zum Schluss möchte ich betonen: „Damit sie mich ganz richtig verstehen“, beschuldige ich nicht die MK-Familie, die Entwicklungsumgebung oder das Softwarepaket, sondern möchte, dass sie für den Benutzer noch besser, komfortabler und attraktiver werden. . Ich habe meine eigene Punktzahl bei TI und ich werde ihnen niemals verzeihen, dass sie National oder die frühere Übernahme von Luminary übernommen haben und anschließend eine interessante MK-Linie getötet haben (obwohl sie sich im letzteren Fall selbst bestraft haben) und auch das, was sie mir 2014 zurückgegeben haben Geld für die bestellten Kristalle (obwohl ich sicherlich die Krim nicht berührt habe), aber dieses tiefe Gefühl hindert mich nicht daran, objektiv zu sein - sie haben gute Arbeit geleistet. Das von der Firma in der Inschrift vorgeschlagene Konzept ist mir nicht zu nahe, aber wahrscheinlich haben sie recht, und für komplexe Kristalle gibt es keinen anderen Weg. Es ist ein Trend und der Kampf damit ist sinnlos.

    Die Tatsache, dass dies ein Trend ist, bestätigt die Situation mit den neuen Kristallen des Power-Managements von Vicor. Der Kristall selbst ist gut (das Gegenteil wäre für ein seriöses Unternehmen überraschend), die Parameter sind sehr gut, und ich erwähnte es nur im Zusammenhang mit dem Abschnitt über die Auswahl externer Komponenten, insbesondere der Induktivität. In der Dokumentation ist dieser Abschnitt nur ein Abschnitt, in dem ein bestimmtes Induktivitätsmodell eines bestimmten Herstellers angegeben ist. Es wird ausdrücklich darauf hingewiesen, dass andere Optionen nicht berücksichtigt werden, siehe Epigraph. Die Gründe des Kristallentwicklers vollständig zu verstehen (die Schaltfrequenz ist hoch, die Ströme sind signifikant, das Entwerfen von Induktivitäten für solche Bedingungen ist nicht trivial). Dennoch sollte ich anmerken, dass dieser Entwurfsansatz für mich ungewöhnlich ist, „aber der Schlüssel hier ist„ für jetzt “. Vielleicht

    Der zweite Teil des Marlezonsky-Balletts.

    Und nun zur Division, deren Verwendung in einer der Bibliotheken von TI gefunden wurde, die aber nicht direkt mit dieser Firma in Verbindung steht, sondern ein Merkmal des gcc-Compilers ist. Wir formulieren das Problem also aus dem Bereich der Adressarithmetik - wir müssen die Differenz in Indizes (nämlich Indizes und nicht Bytes) zwischen zwei Feldelementen (oder einfach nacheinander lokalisierten Daten desselben Typs) berechnen, die durch Zeiger auf sie angegeben werden. In der Regel ist eines der Elemente das erste Element des Arrays, dies ist jedoch nicht wichtig.

    Das Problem selbst ist einfach und die Lösung in C ist offensichtlich und sieht so aus

    $ (pointer1-pointer0) / sizeof (type) $

    . Der Teufel versteckt sich in der Implementierung - das Abteilungs-Team ist in der Standardarchitektur MK nicht standardmäßig implementiert, daher ist es nicht schnell. Wenn der Divisor eine Variable ist, gibt es keine gute Lösung aus dem Wort, aber für einen konstanten Wert gibt es Optionen, die auf Multiplikation basieren. Dank der wunderbaren Multiplikationseigenschaft

    $ (a + b) * (c + d) = a * c + a * d + b * c + b * d $

    (additive Addition, danke, Captain) Die Hardware-Implementierung der Multiplikation ist bei Implementierungen viel häufiger und schnell genug (das Thema Hardware-Multiplikatoren selbst ist interessant, aber jetzt geht es nicht darum). Leider gibt es keine ähnliche Eigenschaft für die Division, weshalb sie in Bezug auf die Hardwareimplementierung ein seltener Gast ist.

    Anstatt zu teilen (durch eine Konstante ist dies wichtig), möchten wir die Multiplikation anwenden, Ihre Hände beobachten

    $ a / c = a * (1 / c) = a * (N / (N * c)) = a * (N / c) / N $

    wobei N eine zusätzliche Konstante ist. Es gibt eine logische Frage - welche Art von Müll, denn jetzt haben wir zwei Divisionsoperationen statt einer und sogar Multiplikation, aufgrund derer der Gewinn entsteht. Die Antwort ist in dem richtig gewählten N, wenn es sich um eine Zweierpotenz handelt, aber die Division wird zu einer Verschiebung der Zahl nach rechts, was viel billiger ist, und wenn der Exponent ein Vielfaches von 8 ist, wird die Division zu einer Umnummerierung der Anzahl von Bytes, was nichts kostet. Da der Faktor N / c konstant ist, berechnen wir ihn im Voraus und alles scheint gut zu sein, wenn es nicht für ein Detail wäre - die Genauigkeit der Darstellung dieses Faktors.

    Betrachten wir den speziellen Fall der Division durch 10, der auftritt, wenn Zahlen von binär in dezimal konvertiert werden. Dann erwarten wir bei H = 256 eine Konstante, die 256/10 = 25,6 multipliziert, und ein Rundungsfehler tritt in ganzen 25 (-2,3%) oder 26 (+1,6) auf %). Dann ist zum Beispiel 100 * 26 = 2600 = 256 * 10 + 40 und der höchste Teil des Ergebnisses ist 10, was dem erwarteten 100/10 = 10 entspricht. Es ist möglich zu berechnen, bei welchen Werten des Dividenden das Ergebnis um mehr als eins von den korrekten abweicht, aber dazu müssen wir Gleichungen der Form lösen

    $ [n / 10] = [n * k / N] + 1 $

    (wobei die Klammern den ganzzahligen Teil mit Abrunden bedeuten), und dies ist keine sehr klare Prozedur. Es ist einfacher, die numerische Simulation zu korrigieren und sicherzustellen, dass das Ergebnis bis zu einem bestimmten n korrekt ist. Sie können einen Korrekturzusatz eingeben und den Genauigkeitsverlust durch die Formel ausgleichen

    $ (n * 26n / 2 + 1) / 256 $

    und den zulässigen Bereich der Dividendewerte deutlich erweitern (bis zu 256, d. h. wir machen bei dem unsignierten 8-Bit-Ganzes niemals einen Fehler), aber der grundlegende Nachteil der Methode kann nicht beseitigt werden - das Vorhandensein eines Fehlers und zusätzlich nur ein Teil notwendig, dies ist jedoch nicht unser Fall), es ist nur eine separate Operation möglich, die die Arbeitsgeschwindigkeit beeinträchtigt. Im Allgemeinen funktioniert die Methode recht gut, ist jedoch in ihrem Umfang eher begrenzt.

    Daher war ich etwas überrascht, als ich in dem kompilierten Code (wie immer dank der Godbolt-Website für die sich bietende Gelegenheit) in der Adreßmultiplikation mit einer (ausreichend großen) Konstanten statt einer Division mit einer Konstanten (sehr klein) sah. Eine andere Frage war, dass die Konstante sich völlig von der für die obige Methode berechneten unterschied. Und zum Schluss wird nicht die obere Hälfte der Arbeit, sondern der jüngere Teil genommen. Im Allgemeinen eine etwas seltsame Methode, etwas Müll, aber Berechnungen zeigen, dass es funktioniert. Eine kurze Überlegung enthüllt das Geheimnis und die Methode erweist sich als absolut richtig, aber ... (natürlich erwartet der Leser "aber ...", da es unmöglich ist, Division durch Multiplikation generell zu ersetzen), er hat Einschränkungen.

    Betrachten Sie die magische Zahl 143 und erkunden Sie ihre lustigen Eigenschaften 77 * 143 = 11011, deren jüngster Teil 011 = 1 = 77/7. Es ist leicht zu sehen, dass 784 * 143 = 112112 ist, sein jüngerer Teil 112 = 784/7 usw. für alle Zahlen, die 999 * 7 nicht überschreiten, = 6993. Hier ist es die natürliche Einschränkung der Methode, aber mit einer weiteren magischen Zahl 7143 erweitern wir den Bereich der Möglichkeiten auf 9999 * 7 = 69993. Andere magische Zahlen mit ähnlichen magischen Eigenschaften lassen sich leicht finden.

    Wie man diese Zahlen erhält - wir wollen eine Zahl finden, indem wir multiplizieren, mit welcher Dividende wir ein Ergebnis erhalten, das in seinem jüngeren Teil das Ergebnis der Division enthält, in diesem Fall mit 7. Es klingt abstrus, aber in der Tat ist alles einfach, für die eingegebene Zahl 7 wollen wir Holen Sie xxx001, nehmen Sie an, xxx = 001 und hier ist es einfach Straßenzauber 1001/7 = 143. Offensichtlich ist 143 * 7 = 1001, dann ist für jede Zahl = n * 7 wahr (n * 7) * 143 = n * (7 * 143) = n * 1001, und der jüngere Teil des Ergebnisses ist n, cht.

    Nun sehen wir einen grundlegenden Fehler in dieser Methode - sie funktioniert nur für Zahlen, die durch einen Divisor teilbar sind, und liefert in allen anderen Fällen ein völlig unvorhersehbares (im Sinne von gar keiner Übereinstimmung der Division) resultierendes Ergebnis der Multiplikation. Wenn wir jedoch für diese spezielle Anwendung die Adressen der Elemente des Arrays subtrahieren, wird das Ergebnis genau ein Vielfaches der Größe der Elemente des Arrays sein, und wir haben das Recht, diese Methode zu verwenden. Wenn wir die falschen Zahlen genommen haben, sollte uns das Ergebnis der Division nicht interessieren: "Die Maschine ist die Mühle, wenn Sie Steine ​​darauf werfen, funktioniert das Mehl nicht."

    Bei der Suche nach magischen Zahlen für andere Teiler als 7 und als Nachweis ihrer Existenz überlassen wir es dem neugierigen Leser. Es ist auch interessant, einen Graphen von Faktoren zu erstellen, der vom Divisor abhängt und die Einbrüche und Gipfel darauf zu sehen. Wahrscheinlich hängt ihre Anwesenheit irgendwie mit der Zahlentheorie zusammen. Zum Beispiel ist für Composite 21 = 3 * 7 diese Zahl = 381 (natürlich ist die Mindestanzahl, der Rest ist nicht interessiert) deutlich geringer als das Produkt 667 * 143 = 95381, und selbst für ihn ist kein Vielfaches, wie ich naiv dachte, obwohl 381 = 381.

    Eine andere interessante Tatsache ist, dass die magischen Zahlen in verschiedenen Zahlensystemen unterschiedlich sein werden. Zum Beispiel gibt es im Dezimalsystem keine Konstante, die durch 5 geteilt werden kann, da keine der Zahlen der Form x ... 1 eine 5 als Divisor haben kann und unsere Methode nicht funktioniert. Gleichzeitig ist dieses Problem im binären (hexadezimalen) System jedoch gelöst, da 1024 + 1 = 1025 = 0x401 by 5 mit dem Ergebnis von 205 = 0xCD wunderbar geteilt wird und unser Algorithmus wieder funktioniert, beispielsweise 130 * 205 = 0x82 * 0xCD = 0xFAFA => FA = 26 = 130/5. Darüber hinaus ist es möglich zu beweisen (nun, ich denke schon), dass die Aufgabe, einen Multiplikator zu finden, für jeden ungeraden Teiler gelöst ist und jeder gerade Teiler zu einer ungeraden endlichen Anzahl von Schichten wird (ich kann es definitiv beweisen). Soweit es sich bei einer bequemen und nützlichen Sache um eine binäre Darstellung handelt, sind wir sehr glücklich damit.

    Ps. Meine ständigen Leser (schmeicheln mir selbst mit der Hoffnung, dass es solche gibt) sind verblüfft - der Posten ist zu Ende, und wo "das Weinen ist Jaroslawna" ist. Mach dir keine Sorgen, mein Schatz, hier ist er.

    Die Debug-Boards für CC1350 und CC1352 verwenden einen Quarz des Antennenschalters (der auf verschiedene Weise verwendet wird, spielt aber keine Rolle), nämlich XMSSJE3G0PA (versuchen Sie nicht, ihn in der russischen Transkription zu lesen, ich bin sicher, dass muRata nichts dergleichen bedeutet). Der Schalter mit bescheidenen Eigenschaften ist also das Frequenzband bis zu 2,7 GHz, die Übertragungsdämpfung beträgt 0,28 dB, die Isolationsdämpfung beträgt 33 dB, die Schaltleistung beträgt 20 dB. Dies alles wird jedoch durch zwei Parameter kompensiert - Abmessungen 1,5 * 1,5 mm und Kosten - 0,9 US-Dollar trotz der verwendeten Technologien "Silicon On Insulator" und "Gallium Arsenid".

    WIE machen sie das - erstens über den Preis, na ja, warum machen wir das nicht - eine rhetorische Frage

    Nur registrierte Benutzer können an der Umfrage teilnehmen. Bitte melden Sie sich an.

    Traktionsumfrage zu diesem Beitrag


    Jetzt auch beliebt: