Constantes et opérateurs

Nommer des valeurs fixes avec #CONSTANT et ENUMERATION, calculer avec chaque opérateur, éviter les pièges de priorité, et choisir les bonnes fonctions intégrées de calcul et de texte.

En un mot#

Une constante est un nom pour une valeur fixe, écrit avec # devant. Les opérateurs combinent des valeurs. La plupart se lisent comme dans n'importe quel BASIC, mais quelques-uns suivent les règles de JavaScript, parce que le BASIC se compile en JavaScript. Ce chapitre les liste tous, avec les pièges qui vont avec.

#CONSTANT#

#CONSTANT <NAME> <value>
#CONSTANT <NAME> = <value>

On la relit avec #<NOM>.

#CONSTANT TITLE "Space Rocks"
#CONSTANT GRAVITY 9.81
#CONSTANT DOUBLE_G = #GRAVITY * 2
Console(#TITLE + " " + Str(#DOUBLE_G))   ' Space Rocks 19.62
  • La valeur est un nombre, une chaîne, ou une expression d'autres constantes.
  • Le nom est insensible à la casse : #title lit #TITLE.
  • Une constante est utilisable au-dessus de sa propre ligne. Les constantes sont posées avant que la première ligne du programme s'exécute.
Console(Str(#MAX_LIVES))   ' 3
#CONSTANT MAX_LIVES 3

Ce qui est refusé#

Un nom déclaré deux fois, ou le nom d'une constante intégrée :

#CONSTANT LIVES 3
#CONSTANT LIVES 5
Duplicate BASIC constant: #LIVES

Le nom d'une commande du catalogue. Le message désigne la commande :

#CONSTANT LEFT 1
BASIC commands require parentheses: Left(...)

Choisissez un nom qu'aucune commande n'utilise, comme #DIR_LEFT.

⚠️ Les pièges#

  • Une constante et une variable écrites exactement pareil, casse comprise, cassent le programme. Il compile, mais il ne démarre pas. #SPEED et speed marchent par hasard, parce que leurs premières graphies diffèrent ; n'en dépendez pas, et donnez-leur des noms différents.

    #CONSTANT SPEED 5
    SPEED = 3
  • Un nom de constante ne porte pas de sigil. #CONSTANT NAME$ "x" compile, mais le programme ne démarre pas.

  • Une constante mal orthographiée ne se découvre qu'à l'exécution de la ligne. #SPEDE compile, et arrête le programme avec SPEDE is not defined.

  • Écrire dans une constante ne se découvre qu'à l'exécution de la ligne. #SPEED = 6 arrête le programme avec Assignment to constant variable.

  • Le #NOM = 5 de PureBasic n'est pas une déclaration hors d'une ENUMERATION. Écrivez #CONSTANT NOM 5.

⚠️ Avec DO … LOOP, les fonctions ne voient pas les constantes#

Dans un programme avec une boucle d'image, les constantes sont posées dans la fonction propre de la boucle. Une FUNCTION qui en lit une arrête le programme.

#CONSTANT MAX_LIVES 3
FUNCTION Lives()
ENDFUNCTION #MAX_LIVES
DO
  Console(Str(Lives()))   ' s'arrête : MAX_LIVES is not defined
  Sync()
LOOP

Copiez la constante dans un GLOBAL, et lisez le GLOBAL dans la fonction :

#CONSTANT MAX_LIVES 3
GLOBAL maxLives = #MAX_LIVES
FUNCTION Lives()
ENDFUNCTION maxLives
DO
  Console(Str(Lives()))   ' 3
  Sync()
LOOP

La même limite vaut pour les variables ordinaires : voir Variables et types.

Les constantes intégrées : #AK_*#

aukimi définit 61 constantes, toutes nommées #AK_…. Elles nomment les options que prennent les commandes, pour que votre code ne dépende pas de nombres bruts. Voici la liste complète.

FamilleConstantes et valeursSert à
AUTO#AK_AUTO_ID = -1laisser une commande de création choisir l'identifiant
ERROR#AK_ERROR_IGNORE = 0, #AK_ERROR_REPORT = 1, #AK_ERROR_STOP = 2la politique d'erreur de ErrorMode
TEXT#AK_TEXT_ASCII = 0, #AK_TEXT_UTF16 = 1, #AK_TEXT_UTF8 = 2les encodages de texte
MATCH#AK_MATCH_EXACT = 0, #AK_MATCH_FOLD_CASE = 1sensible à la casse ou non
ORDER#AK_ORDER_LOW_TO_HIGH = 0, #AK_ORDER_HIGH_TO_LOW = 1, #AK_ORDER_FOLD_CASE = 2le tri
ESCAPE#AK_ESCAPE_NATIVE = 0, #AK_ESCAPE_MARKUP = 1, #AK_ESCAPE_DATA = 2l'échappement de texte
LIST#AK_LIST_LAST = 0, #AK_LIST_FIRST = 1, #AK_LIST_BEFORE = 2, #AK_LIST_AFTER = 3les positions dans une liste
DATA#AK_DATA_NULL = 0, #AK_DATA_TEXT = 1, #AK_DATA_NUMBER = 2, #AK_DATA_FLAG = 3, #AK_DATA_LIST = 4, #AK_DATA_RECORD = 5, #AK_DATA_PRETTY = 1les valeurs JSON et de dictionnaire
PATTERN#AK_PATTERN_DOT_NEWLINE = 1, #AK_PATTERN_IGNORE_SPACES = 2, #AK_PATTERN_LINE_ANCHORS = 4, #AK_PATTERN_ANY_NEWLINE = 8, #AK_PATTERN_FOLD_CASE = 16les options des expressions régulières
TIME#AK_TIME_PART_YEAR = 0, #AK_TIME_PART_MONTH = 1, #AK_TIME_PART_WEEK = 2, #AK_TIME_PART_DAY = 3, #AK_TIME_PART_HOUR = 4, #AK_TIME_PART_MINUTE = 5, #AK_TIME_PART_SECOND = 6, #AK_TIME_LOCAL = 0, #AK_TIME_UTC = 1les dates
CONFIG#AK_CONFIG_COMPACT = 1, #AK_CONFIG_SECTION_GAPS = 2, #AK_CONFIG_NO_BOM = 4les fichiers de préférences
HASH#AK_HASH_CRC32 = 1, #AK_HASH_SHA1 = 2, #AK_HASH_SHA256 = 3, #AK_HASH_HMAC = 256StringFingerprint, FileFingerprint
PACK#AK_PACK_FAST = 1, #AK_PACK_BALANCED = 6, #AK_PACK_MAX = 9, #AK_PACK_SAFE_LIMIT = 32000000la compression
XML#AK_XML_ROOT = 0, #AK_XML_ELEMENT = 1, #AK_XML_COMMENT = 2, #AK_XML_CDATA = 3, #AK_XML_DOCTYPE = 4, #AK_XML_INSTRUCTION = 5, #AK_XML_OK = 0, #AK_XML_INVALID = 1, #AK_XML_PRETTY = 1, #AK_XML_NO_DECLARATION = 2les nœuds et la sortie XML
ErrorMode(#AK_ERROR_REPORT)
Console(Str(#AK_ERROR_STOP))   ' 2
  • Elles se lisent comme vos propres constantes, dans n'importe quelle casse : #ak_error_stop marche.
  • Vous ne pouvez pas en redéfinir une : #CONSTANT AK_ERROR_STOP 5 est un doublon.
  • Les drapeaux dont les valeurs sont des puissances de deux (PATTERN, CONFIG, #AK_HASH_HMAC) se combinent avec ||, le « ou » bit à bit.
  • Il n'y a ni constantes #PB_* ni constantes AGK. Un programme qui s'en sert reçoit … is not defined quand la ligne s'exécute.

ENUMERATION et ENUMERATIONBINARY#

ENUMERATION [<Name>] [<start> [STEP <step>]]
  #<NAME> [= <value>]
  ...
ENDENUMERATION

ENUMERATIONBINARY [<Name>] [<start>]
  #<NAME> [= <value>]
  ...
ENDENUMERATION

Une énumération déclare une suite de constantes, une par ligne.

ENUMERATION
  #RED
  #GREEN
  #BLUE
ENDENUMERATION
Console(Str(#RED) + Str(#GREEN) + Str(#BLUE))   ' 012
ENUMERATION 10 STEP 5
  #A
  #B
  #C = 100
  #D
ENDENUMERATION
Console(Str(#A) + " " + Str(#B) + " " + Str(#C) + " " + Str(#D))   ' 10 15 100 105
ENUMERATIONBINARY
  #FLAG_A
  #FLAG_B
  #FLAG_C
ENDENUMERATION
Console(Str(#FLAG_A) + " " + Str(#FLAG_B) + " " + Str(#FLAG_C))   ' 1 2 4
RègleDétail
ENUMERATIONpart de 0 et ajoute 1, ou part de <start> et ajoute <step>
ENUMERATIONBINARYpart de 1 (ou de <start>) et double : 1, 2, 4, 8…
#NOM = <valeur>fixe cette valeur ; les entrées suivantes repartent d'elle
les valeursdes nombres entiers : 0.5 est arrondi à 1
<start>, <step>, <valeur>des nombres, ou des expressions d'autres constantes ; aucun appel de commande
une énumération nomméereprend là où elle s'était arrêtée quand on la rouvre
ENUMERATION Tiles
  #FLOOR
  #WALL
ENDENUMERATION
ENUMERATION Tiles
  #DOOR
ENDENUMERATION
Console(Str(#DOOR))   ' 2

Refusé :

Vous écrivezMessage
une ligne sans # dans le blocBASIC enumeration accepts only #Constant entries
deux noms sur une ligne (#A, #B)même message
ENUMERATIONBINARY 1 STEP 2ENUMERATIONBINARY does not accept STEP
une énumération dans une autreNested BASIC enumerations are not supported
une énumération nommée rouverte dans l'autre modeBASIC enumeration Tiles cannot change between sequential and binary modes
#A = Random(1, 2)BASIC enumeration values must be constant numeric expressions

Un STEP exige une valeur de départ : écrivez ENUMERATION 0 STEP 2.

L'arithmétique#

OpérateurSensExempleRésultat
+addition7 + 29
-soustraction, ou opposé7 - 25
*multiplication7 * 214
/division, avec décimales7 / 23.5
DIVdivision, partie entière7 DIV 23
^puissance7 ^ 249
Mod(a, b)resteMod(7, 2)1
a = 7
b = 2
Console(Str(a / b))      ' 3.5
Console(Str(a DIV b))    ' 3
Console(Str(-7 DIV 2))   ' -3
Console(Str(Mod(a, b)))  ' 1
Console(Str(Mod(-7, 3))) ' -1
Console(Str(a ^ b))      ' 49
  • / garde toujours les décimales, même entre deux entiers.
  • DIV les laisse tomber, vers zéro : -7 DIV 2 vaut -3.
  • La division par zéro : / donne Infinity ; DIV arrête le programme avec BASIC integer division by zero.
  • Le reste prend le signe du premier nombre : Mod(-7, 3) vaut -1.

⚠️ MOD s'écrit comme un appel#

L'opérateur MOD des autres BASIC est refusé, parce que le catalogue a une commande Mod :

r = 7 MOD 2
BASIC commands require parentheses: Mod(...)

Écrivez Mod(7, 2). Pour des décimales, FMod(7.5, 2) donne 1.5.

⚠️ DIV prend ses deux voisins#

DIV marche entre deux valeurs simples : nombres, variables, cases de tableau, champs d'enregistrement, ou un groupe entre parenthèses à sa gauche.

  • Il passe avant * et / : 2 * 7 DIV 2 vaut 2 * 3, donc 6.

  • Après un appel de commande, il casse le programme, qui ne démarre pas :

    s$ = "hello"
    half = Len(s$) DIV 2
  • Devant un groupe entre parenthèses, il est refusé :

    a = 9
    b = 4
    x = a DIV (b - 1)
    Unknown BASIC command: DIV()
    

Mettez d'abord l'appel ou le groupe dans une variable :

a = 9
b = 4
d = b - 1
x = a DIV d
Console(Str(x))   ' 3

⚠️ ^ et le signe moins#

  • ^ se groupe par la droite : 2 ^ 3 ^ 2 vaut 2 ^ 9, donc 512.

  • Un signe moins (ou NOT) juste devant une puissance n'est pas permis. Le programme ne démarre pas :

    x = 2
    y = -x ^ 2

    Écrivez -(x ^ 2) pour −4, ou (-x) ^ 2 pour 4. 2 ^ -2 va très bien : 0.25.

Les comparaisons#

OpérateurSens
=égal
<>différent
<, >plus petit, plus grand
<=, >=plus petit ou égal, plus grand ou égal
a = 5
same = (a = 5)
differ = (a <> 5)
Console(Str(same) + " " + Str(differ))   ' 1 0
loose = ("5" = 5)
Console(Str(loose))   ' 0 : un texte n'est jamais égal à un nombre
IF a >= 5 THEN Console("cinq ou plus")   ' cinq ou plus
  • Une comparaison rangée dans une variable vaut 1 ou 0. Dans IF, WHILE et UNTIL, elle est simplement vraie ou fausse.
  • À droite d'une affectation, = compare. same = (a = 5) ne change pas a. Les parenthèses sont facultatives, mais plus claires.
  • L'égalité est stricte : le texte "5" n'est pas le nombre 5. Convertissez d'abord avec Val ou Str.
  • Les textes se comparent dans l'ordre des codes de caractère : "B" < "a".

⚠️ Dans un appel, = n'est pas une comparaison#

Dans une instruction qui est un appel de commande, un = entre les parenthèses affecte. La variable change, sans bruit.

a = 5
Console(Str(a = 1))   ' 1, et a vaut maintenant 1
Console(Str(a))       ' 1

Comparez d'abord dans une variable, ou dans un IF.

⚠️ == et != comparent large#

== et != sont acceptés, mais ce sont les comparaisons larges de JavaScript : textes et nombres sont convertis avant d'être comparés.

c$ = "7"
n = 7
IF c$ = n THEN Console("jamais affiché")
IF c$ == n THEN Console("== compare large")   ' == compare large

Utilisez = et <>.

Les opérateurs logiques : AND, OR, NOT#

x = 5
y = 0
IF x > 0 AND y = 0 THEN Console("les deux")       ' les deux
IF x < 0 OR y = 0 THEN Console("l'un des deux")   ' l'un des deux
IF NOT y THEN Console("y vaut zéro")              ' y vaut zéro
r = x > 0 AND y = 0
Console(Str(r))   ' 1
  • NOT est vrai pour 0, une chaîne vide et FALSE, et faux pour tout le reste.
  • Le côté droit n'est évalué que si c'est utile : dans a AND b, b est sauté quand a est faux.

⚠️ Sur de simples nombres, AND et OR rendent l'un de leurs opérandes, pas 1 ou 0. Les BASIC classiques calculent sur les bits ; aukimi non.

v = 5 AND 3
Console(Str(v))   ' 3 : le second opérande
w = 0 OR 7
Console(Str(w))   ' 7

Pour les bits, prenez les opérateurs bit à bit ci-dessous.

Les opérateurs bit à bit#

aukimiSensExempleRésultat
&&et%1100 && %10108
||ou%1100 || %001115
~~ou exclusif%1100 ~~ %10106
!non (chaque bit inversé)!0-1
<<décalage à gauche1 << 416
>>décalage à droite, signe conservé-16 >> 2-4
flags = %1100
Console(Str(flags && %1010))   ' 8
Console(Str(flags || %0011))   ' 15
Console(Str(flags ~~ %1010))   ' 6
Console(Str(!0))               ' -1
Console(Str(1 << 4))           ' 16
Console(Str(-16 >> 2))         ' -4

Les symboles travaillent sur les bits, les mots sont logiques. && n'est pas AND, et || n'est pas OR. C'est l'inverse du C et de JavaScript.

Les opérateurs bit à bit travaillent sur des entiers signés de 32 bits.

⚠️ XOR n'existe pas. Il compile, mais le programme ne démarre pas. Écrivez ~~.

x = 5 XOR 3

⚠️ Un & seul ne joint pas des chaînes. "a" & "b" donne 0. Joignez avec +.

⚠️ Un test de bit exige des parenthèses#

&& passe après = dans l'ordre des opérations. flags && 4 = 4 veut dire flags && (4 = 4).

flags = 4
IF flags && 4 = 4 THEN Console("jamais affiché")
IF (flags && 4) = 4 THEN Console("bit levé")   ' bit levé
IF flags && 4 THEN Console("levé aussi")        ' levé aussi

Le texte#

+ joint des chaînes. Quand un côté est du texte et l'autre un nombre, le nombre est transformé en texte.

score = 10
Console("Score : " + Str(score))  ' Score : 10
Console("n" + 5)                  ' n5
Console(Str(5 + "5"))             ' 55
Console(Str(10 - "3"))            ' 7

⚠️ -, * et / transforment le texte en nombre, mais + transforme le nombre en texte. Convertissez exprès : Str pour faire du texte, Val ou ValFloat pour faire un nombre.

Les chaînes à {trous}, comme $"Score : {score}", sont dans Les raccourcis.

TRUE, FALSE, NULL#

MotValeur
TRUE, FALSEdes valeurs de vérité (pas les nombres 1 et 0)
NULLaucune valeur ; le départ d'une HANDLE

Ils s'écrivent dans n'importe quelle casse.

ready = TRUE
Console(Str(ready))   ' true
IF ready THEN Console("prêt")   ' prêt
IF ready = 1 THEN Console("jamais affiché")
done = (3 > 2)
Console(Str(done))    ' 1

⚠️ TRUE n'est pas 1. Une variable qui vaut TRUE s'affiche true et n'est pas égale à 1. Testez-la avec IF ready THEN. Une comparaison, elle, range 1 ou 0.

L'ordre des opérations#

Du premier au dernier. Les opérateurs d'une même ligne vont de gauche à droite, sauf ^.

OrdreOpérateurs
1( ), appels
2DIV, avec ses deux voisins
3^ (par la droite)
4NOT, !, le signe moins
5*, /
6+, -
7<<, >>
8<, <=, >, >=
9=, <> (et ==, !=)
10&&
11~~
12||
13AND
14OR

⚠️ Les pièges#

Vous écrivezCela veut direÉcrivez plutôt
NOT a = b(NOT a) = ba <> b
flags && 4 = 4flags && (4 = 4)(flags && 4) = 4
2 * 7 DIV 22 * (7 DIV 2) = 6t = 2 * 7 puis t DIV 2
2 ^ 3 ^ 22 ^ 9 = 512(2 ^ 3) ^ 2 pour 64
-x ^ 2refusé : le programme ne démarre pas-(x ^ 2)
1 < x < 5(1 < x) < 5, toujours vraix > 1 AND x < 5
a = 1
b = 2
IF NOT a = b THEN Console("jamais affiché")
IF a <> b THEN Console("a et b diffèrent")   ' a et b diffèrent
same = (a = b)
IF NOT same THEN Console("pas pareils")      ' pas pareils

Les fonctions intégrées#

Deux sortes de fonctions se ressemblent dans votre code.

Prises en charge par le compilateur#

NomCe qu'il fait
Float(x)transforme x en nombre : Float("2.5") vaut 2.5
Max(a, b, …)la plus grande d'autant de valeurs qu'on veut
Min(a, b, …)la plus petite d'autant de valeurs qu'on veut
PI3.141592653589793 (en majuscules seulement)
TRUE, FALSE, NULLvoir plus haut
Console(Str(Max(3, 9, 12)) + " " + Str(Min(4, -1, 2)))   ' 12 -1
Console(Str(Float(7) / 2))   ' 3.5

Venues du catalogue#

Tout le reste est une commande du catalogue, même les noms classiques de calcul et de texte. Chacune a sa page dans la référence des commandes.

La trigonométrie du catalogue travaille en degrés. Sin(90) vaut 1. Les versions en radians finissent par Rad.

Console(Str(Sin(90)))           ' 1
Console(Str(Cos(180)))          ' -1
Console(Str(ATan2(1, 1)))       ' 45
Console(Str(SinRad(PI / 2)))    ' 1
Console(Str(Sin(PI / 2)))       ' 0.027412133592044294 : PI / 2 degrés
FonctionRésultatNote
Sin, Cos, Tand'un angle en degrés
ASin, ACos, ATan, ATan2(y, x)un angle en degrés
SinRad, CosRad, TanRadd'un angle en radians
Sqrt(x), Pow(a, b), Abs(x)
Exp(x), Log(x), Log10(x)Log est le logarithme népérien
Int(x), Trunc(x)la partie entière, vers zéroInt(-3.7) vaut -3
Floor(x), Ceil(x)vers le bas, vers le hautFloor(-3.2) vaut -4
Round(x)l'entier le plus proche ; .5 monteRound(2.5) vaut 3, Round(-2.5) vaut -2
Mod(a, b), FMod(a, b)reste ; entier, décimalsigne de a
Sign(x)-1, 0 ou 1
Random(from, to)un nombre entier, bornes comprises
Str(n), Str(n, decimals)du texteStr(3.14159, 2) vaut 3.14
Val(s), Val(s, base)un nombre entierVal("1.5") vaut 1, Val("ff", 16) vaut 255
ValFloat(s)un nombre décimalValFloat("1.5") vaut 1.5
Len(s)le nombre de caractères
Left(s, n), Right(s, n)les n premiers ou derniers caractères
Mid(s, start, length)une partie de sstart compte à partir de 1
Upper(s), Lower(s)
Chr(code), Asc(s)un caractère d'après son code, et l'inverseChr(34) est "
Hex(n), Bin(n)du texte en base 16 ou 2Hex(255) vaut FF
FindString(s, find)la position, à partir de 1 ; 0 si absent
Console(Str(Int(-3.7)) + " " + Str(Floor(-3.7)))   ' -3 -4
Console(Mid("hello", 2, 3))                         ' ell
Console(Str(FindString("hello", "l")))              ' 3

⚠️ RND et INSTR de QBasic n'existent pas. Ils sont refusés comme commandes inconnues. Écrivez Random(from, to) et FindString(s, find).

x = RND(5)
p = INSTR("hello", "l")

⚠️ Int tronque ; il n'arrondit pas vers le bas. INT(-3.7) de QBasic vaut −4 ; Int(-3.7) d'aukimi vaut −3. Prenez Floor pour −4.

⚠️ Le Sin de PureBasic prend des radians ; celui d'aukimi des degrés. Prenez SinRad quand vos angles sont en radians.

Vous venez d'un autre BASIC#

Vous écrivezDans aukimi
a MOD bMod(a, b)
a XOR ba ~~ b
a AND b sur des bitsa && b
a OR b sur des bitsa || b
NOT a sur des bits!a
a & b pour joindre du texte (Visual Basic)a + b
a \ b (division entière)a DIV b
#NOM = 5 (PureBasic)#CONSTANT NOM 5
CONST NOM = 5#CONSTANT NOM 5
RND, INSTR, INTRandom, FindString, Floor
Sin(x) avec x en radiansSinRad(x)